Servlets (Básico)

Todos los m�todos de servicio de un servlet deber�an estar terminados cuando se elimina el servlet. El servidor intenta asegurarse llamando al m�todo destroy s�lo despu�s de que todas las peticiones de servicio hayan retornado, o despu�s del periodo de tiempo de gracia espec�fico del servido, lo que ocurra primero. Si nuestro servlet tiene operaciones que tardan mucho tiempo en ejecutarse (esto es, operaciones que tardan m�s que el tiempo concedido por el servidor), estas operaciones podr�an estar ejecut�ndose cuando se llame al m�todo destroy. Debemos asegurarnos de que cualquier thread que maneje peticiones de cliente se hayan completado; el resto de est� p�gina describe una t�cnica para hacer esto.

Si nuestro servlet tiene peticiones de servicio potencialmente largas, debemos utilizar las t�cnicas de esta lecci�n para.

  • Seguir la pista de cuantos threads est�n ejecutando el m�todo service actualmente.
  • Proporcionar una limpieza de desconexi�n haciendo que el m�todo destroy notifique a los threads la desconexi�n y espere a que ellos se hayan completado.
  • Haciendo que todos los m�todos de larga duraci�n comprueben peri�dicamente la desconexi�n y, si es necesario, paren su trabajo, limpien y retornen.

.�Peticiones de Seguimiento de Servicio

Para seguir la pista a una petici�n de servicio, incluimos un campo en nuestra clase servlet que cuente el n�mero de m�todos de servicio que se est�n ejecutando. El campo deber� tener acceso a m�todos para incrementar, decrementar y devolver su valor. Por ejemplo.

public ShutdownExample extends HttpServlet {
    private int serviceCounter = 0;
    ...
    //Access methods for serviceCounter
    protected synchronized void enteringServiceMethod() {
	serviceCounter++;
    }
    protected synchronized void leavingServiceMethod() {
        serviceCounter--;
    }
    protected synchronized int numServices() {
	return serviceCounter;
    }
}

El m�todo service deber�a incrementar el contador de servicios cada vez que se entre en �l y decrementarlo cada vez que se salga de �l. Esta es una de las pocas veces que al subclasificar la clase HttpServlet debamos sobreescribir el m�todo service. El nuevo m�todo deber�a llamar al super.service para preservar la funcionalidad del m�todo HttpServlet.service original.

    protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
	enteringServiceMethod();
	try {
            super.service(req, resp);
        } finally {
            leavingServiceMethod();
        }
    }

.�Proporcionar Limpieza a la Desconexi�n

Para proporcionar esta limpieza, nuestro m�todo destroy no deber�a destruir ning�n recurso compartido hasta que todas las peticiones de servicio se hayan completado. Una parte de esto es chequear el contador de servicos. Otra parte es notificar a los m�todos de larga duraci�n que es la hora de la desconexi�n. Para esto, se necesita otro campo con sus m�todos de acceso normales. Por ejemplo.

public ShutdownExample extends HttpServlet {
    private Boolean shuttingDown;
    ...
    //Access methods for shuttingDown
    protected setShuttingDown(Boolean flag) {
	shuttingDown = flag;
    }
    protected Boolean isShuttingDown() {
	return shuttingDown;
    }
}

Abajo podemos ver un m�todo destroy que utiliza estos campos para proporcionar una limpieza de desconexi�n.

    public void destroy() {

        /* Check to see whether there are still service methods running,
	 * and if there are, tell them to stop. */
	if (numServices() > 0) {
	    setShuttingDown(true);
        }

	/* Wait for the service methods to stop.  */
	while(numServices() > 0) {
            try {
                Thread.sleep(interval);
            } catch (InterruptedException e) {
            }
        }
    }

.�Crear M�todos de Larga Duraci�n Educados

El paso final para proporcionar una limpieza de desconexi�n es crear m�todos de larga duraci�n que sean educados. Estos m�todos deber�an comprobar el valor del campo que notifica las desconexiones, e interrumpir su trabajo si es necesario. Por ejemplo.

    public void doPost(...) {
        ...
	for(i = 0; ((i < lotsOfStuffToDo) && !isShuttingDown()); i++) {
	    try {
		partOfLongRunningOperation(i);
	    } catch (InterruptedException e) {
            }
        }
    }

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP