JobMonitor
O JobMonitor é o serviço do BISFW que permite que tarefas sejam executar em uma Thread paralela para que a thread principal não fique bloqueada esperando. Esse recurso é extremamente útil para tarefas demoradas, uma vez que permite retornar status sobre a execução da tarefa enquanto ela acontece, mesmo que seja pela interface WEB.
Criando o Job
Para colocar uma tarefa em background basta implementar a classe Job e iniciar a execução dentro do método runJob().
![]() |
Exemplo Tarefa em Execução em Background
Job job = new Job("Título da Tarefa") { //O título da tarefa é colocado no título da thread, o que ajuda no DEV.
@Override
public Object runJob(Job job, JobStatus jobStatus) throws Throwable {
//Código para execução da tarefa...
}
};
job.start(); //inicia a tarefa
|
Quando a tarefa iniciar, o método runJob() receberá dois parâmetros:
- job - referência da própria instância do Job criado.
- jobStatus - Instância do objeto de status do job. Dentro desse objeto a tarefa deve atualizar as propriedades como "mensagens", percentual de tarefa realizada, etc..
![]() |
|
Interrompendo o Job
O cancelamento do Job em segundo plano pode ser solicitado pelo usuário. Para que isso ocorra a interface deve chamar o método interrupt() do JobStatus. Ao chamar esse método o JobStatus ficará marcado que a tarefa obteve a solicitação de cancelamento de sua execução.
Note que depende do Job Implementado verificar se essa solicitação foi realizada e parar a execução da tarefa tomando as providências necessárias (como dar rollback em tarefas pela metade ou concluí-las e cancelar depois, etc.). Há duas maneiras do Job verificar esse cancelamento:
- Verificação Manual - Na verificação manual o desenvolvedor pode utilizar o método getInterruptResquested() e obter o valor do atributo. Caso true, indica que a solicitação de cancelamento foi realizada e deste ponto em diante direcionar o método para os procedimentos de cancelamento, e lançar a exception.
- Recomendado lançar a exception:
throw new BISValidationException("FW_ERROR_000004");
Este Código de exception é utilizado para identificar que a operação foi cancelada pelo usuário.
- Recomendado lançar a exception:
- Verificação Automática - Neste modo basta o desenvolvedor incluir a chamada do método checkInterrupt() do JonMonitor. Este método verifica o status do atributo e se tiver em true já lança a exception como citada acima (Validation com o código 'FW_ERROR_000004'). Só é preciso tomar cuidado para que o próprio código do Job não trate a exception e deixe que ela vaze para fora do método do Job.
- Note que neste método a exception é lançada diretamente, assim, o método que verifica o status deve ser bem posicionado. Ou realizar as tratativas no catch/finally.
JobMonitor
O JobMonitor é uma classe estática, como um Singleton, que controla e mantém todos os Jobs do Sistema. Ao criar uma instância de Job ele automaticamente se registra no JobMonitor. Mesmo antes de iniciar a tarefa o JobMonitor já tem a referência da classe e monitora seu status.
Quando o Job é criado, ela cria também uma instância final da JobStatus que tem um identificador único (UUID). Este UUID é o identificador do Job e pode ser utilizado para realizar operações no JobMonitor.
![]() |
|
Ao criar um Job, devemos nos preocupar em salvar o JobStatus, ou ao menos o UUID para que seja possível referenciar a tarefa em background a partir do JobMonitor.
![]() |
Exemplo de Criação do Job e Obtenção do Status a partir do JobMonitor
//Implementação do Job
Job job = new Job("Título da Tarefa") { ... };
//Recuepra o objeto que mantém o status de progresso diretamente da tarefa
JobStatus status = job.getStatus();
//Obtemos e salvamos para referência futura o UUID do Job
String uuid = status.getUuid();
//Obtendo o JobStatus a partir do JobMonitor com o UUID do job.
JobStatus status2 = JobMonitor.getJobStatus(uuid);
|
Note que no exemplo acima o .start() do job pode ser dado a qualquer momento. O job não precisa estar sendo executado para que todo o restante funcione.
![]() |
|
JobChecker
JobChecker é a implementação de uma Thread que verifica periodicamente a tarefa sem segundo plano e notifica conforme atualização do objeto de status.
Para criar o JobChecker basta passar o UUID do job na sua construção:
![]() |
JobChecker verificando o progresso da tarefa
JobChecker jobChecker = new JobChecker(uuid, true) {
@Override
public void updateStatus(JobStatus jobStatus) {
// Código para lêr o conteúdo do JobStatus e atualizar qualquer sistema
// Abaixo um código exemplo para atualizar o conteúdo da tela do Vaadin.
// É necessário obter a UI do usuário e criar uma classe de acesso primeiro
ui.access(new Runnable() {
@Override
public void run() {
// Código do Vaadin para atualizar a UI do usuário
}
});
}
};
|
Note que no construtor foi passado além da UUID um booleano 'true'. Esse boleano indica se quando o JobChecker detectar que a tarefa finalizou ele mesmo se encarrega de avisar o JobMonitor que ele pode descartar a tarefa e seu status.
Isso é importante porque mesmo que o Job termine, o JobMonitor não sabe até quando deve guardar a referência do JobStatus para ser consultado, assim é importante que o descarte seja autorizado para economizar recursos.
Para forçar esse descarte manualmente, caso não se use o JobChecker ou se passe o atributo como false, deve ser chamado o método:
JobMonitor.cleanJob(uuid);
Caso esse método não seja chamado, no momento em que este documento é escrito, o JobMonitor tem um tempo limite de 6h para manter o Job em memória desde o momento em que a instância do Job é criado. Quando o job é removido de forma forçada, um logImprovement() é chamado com o título do Job.
Job & SessionManager
Ao criar um novo objeto Job, ele mesmo tenta detectar se estamos em um ambiente com uma Session associada a Thread atual. Se encontrar ele automaticamente transfere a sessão de autenticação atual para a nova Thread do Job. A vantagem dessa operação é que o método SessionManager.getSession() passará a funcionar dentro do método run() do Job, bem como permitirá que outros serviços como FWLogger encontre a sessão do usuário.
![]() |
|