Hilos y gvSIG (2 de 4): TaskStatus

En el articulo anterior, “Hilos y gvSIG (1 de 4)“, vimos una introducción a lo que podían ser la herramientas que nos ofrece gvSIG para crear nuestros propios procesos sin que estos bloqueen la interface de usuario de gvSIG.
Vamos a continuar con ello viendo las utilidades relacionadas con el TaskStatus.

Para gestionar el estado y progreso de tareas o procesos en gvSIG disponemos del mecanismo de TaskStatus, que se encuentra implementado en la librería de org.gvsig.tools. Las principales entidades relacionadas con este mecanismo que nos encontraremos serán:

  • TaskStatus. Que representa el estado en el que se encuentra un proceso o tarea. Tiene métodos para consultar el estado en que se encuentra la tarea, pero no para establecerlo. Este interface es el que deben usar los procesos que quieren consultar el estado de otros procesos.
  • TaskStatusManager. Hace de factoría para la creación de TaskStatus, así como mantiene un registro de éstos para poder consultar el estado de las tareas que se encuentren en ejecución.
  • SimpleTaskStatus. Extiende el interface TaskStatus con métodos que nos permiten actualizar el estado de la tarea. Es usado por la propia tarea o proceso para mantener actualizado la información de su estado.
  • AbstractMonitorableTask. Se trata de una clase abstracta que extiende a la clase Thread, añadiéndole métodos para obtener el TaskStatus asociado a éste. Normalmente cuando creemos nuestros procesos extenderemos de esta clase en lugar de la clase Thread.

El TaskStatus, nos da información sobre el estado del proceso, nos informa de características del proceso como:

  • Si se puede determinar la duración del proceso. Es decir si es posible calcular qué llevamos y cuánto falta (isIndeterminate).
  • Si el proceso es cancelable o no (isCancelable).
  • Un titulo identificativo del proceso (getTitle)

También nos permite consultar el progreso de nuestro proceso:

  • Consultar el porcentaje de avance de éste (getCompleted)
  • O una etiqueta que identifique qué esta haciendo en un momento dado (getLabel).

Nos permite solicitar la cancelación del proceso (cancelRequest). No nos permite cancelarlo, esto es algo que el propio proceso debe decidir, desde fuera lo único que podemos hacer es pedir que cancele su ejecución.

Y por último consultar su estado:

  • isRunning, el proceso está en ejecución.
  • isRequestCanceled, el proceso está en ejecución y se ha solicitado su cancelación.
  • isAborted, el proceso ha abortado su ejecución, normalmente debido a algún error durante la ejecución de éste.
  • isCancelled, el proceso se ha cancelado por petición externa a éste, normalmente por la intervención del usuario o de algún otro proceso invocando al método cancelRequest.

El TaskStatusManager, nos permite crear instancias de TaskStatus mediante el método createDefaultSimpleTaskStatus, y añadir, consultar, o eliminar un TaskStatus de la lista de status que mantiene.

Tanto el TaskStatus, como el TaskStatusManager son observables, y permiten registrar observadores para poder seguir el estado de una tarea. Así si quisiésemos presentar información de las tareas que hay en ejecución en un momento dado solo tendríamos que registrarnos como observadores del taskStatusManager. Si lo hiciésemos tendríamos que tener la precaución de asegurarnos en el método update de nuestro observador que estamos en el hilo de ejecución de swing antes de presentar la información en el interface gráfico. Podría ser algo como:

class MyObserver implements Observer {
  public void update(final Observable observable,final Object notification) {

    if (!SwingUtilities.isEventDispatchThread()) {
      SwingUtilities.invokeLater(new Runnable() {

        public void run() {
          update(observable,notification);

        }
      });
      return;
    }
    ...
    Procesar notificacion
    ...

  }
}

Si estamos observando al TaskStatusManager recibiremos como observable a éste y como notification el TaskStatus involucrado o null. Por ejemplo, añadir un taskstatus al manager o modificar un taskstatus registrado en el manager provocará que nos llegue como notification el taskstaus añadido o modificado y cuando se elimine uno nos llegara el que queremos eliminar o null.

El otro interface importante relacionado con TaskStatus es el SimpleTaskStatus. Se trata del interface que usará un proceso o tarea para mantener actualizado su estado. Añade los siguientes métodos al TaskStatus:

  • add y remove, que provocaran que el TaskStatus se registre o elimine en el manager para poder estar en la lista de tareas disponibles de forma publica.
  • setAutoremove y getAutoremove, que nos permitirán consultar y fijar la propiedad autoremove, que indica si el TaskStatus deberá ser eliminado del manager al terminar su ejecución de forma automática o no.
  • setCancelable para indicar si nuestro proceso es cancelable o no.
  • terminate para indicar que nuestro proceso ha terminado su ejecución y además lo ha hecho de forma correcta.
  • cancel para indicar que nuestro proceso ha terminado su ejecución debido a una petición de cancelación.
  • abort para indicar que nuestro proceso ha terminado su ejecución debido a una condición de error.
  • setRangeOfValues y setCurValue para que indiquemos, si procede, cuál va a ser la duración del proceso y en qué estado se encuentra. Estos valores serán usados para calcular el getCompleted y el isIndeterminate.
  • setTitle y message para ofrecer una información textual del avance del proceso.

Normalmente no crearemos directamente un TaskStatus, sino que para crear nuestro propio proceso extenderemos de la clase AbstractMonitorableTask. Esta instanciará y registrará en el manager una instancia de TaskStatus, añadiendo los métodos:

  • cancelRequest, que nos permitirá solicitar la cancelación de nuestro hilo.
  • getTaskStatus, que nos permitirá obtener el TaskStatus asociado al hilo.

Con todas estas piezas a nuestra disposición vamos a ver cómo podríamos hacer una pequeña extensión para gvSIG que lance un proceso en un hilo aparte, y cómo habría que hacer en este hilo para ir informando del progreso de su ejecución a gvSIG y que éste pueda mostrar esa información.

Crearemos tres clases:

  • MyExtension, que será la encargada de lanzar nuestro proceso, controlando que no se pueda volver a lanzar mientras no haya terminado la ejecución de éste.
  • MyProcess, que extenderá a AbstractMonitorableTask, y tendrá el código de nuestro proceso.
  • MyDialog, que representara un pequeño cuadro de dialogo con algunas propiedades que puede requerir nuestro proceso.

En el próximo articulo,”Hilos y gvSIG (3 de 4): Estructura de nuestro proceso“,  continuaremos viendo cómo estructurar nuestra extensión y nuestro proceso.

Un saludo

Joaquin

About Joaquin del Cerro

Development and software arquitecture manager at gvSIG Team. gvSIG Association
This entry was posted in development, gvSIG Desktop, spanish and tagged . Bookmark the permalink.

2 Responses to Hilos y gvSIG (2 de 4): TaskStatus

  1. Pingback: Hilos y gvSIG (1 de 4) | gvSIG blog

  2. Pingback: Hilos y gvSIG (3 de 4): Estructura de nuestro proceso | gvSIG blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s