Scheduler

De BIS Wiki
Revisão de 13h56min de 20 de outubro de 2020 por Rodrigogml (discussão | contribs) (Funcionamento)
Ir para navegação Ir para pesquisar

O Scheduler é o serviço de agendamento de tarefas do BISFW. o Scheduler pode agendar tarefas do FWTask para serem executadas de forma única ou repetidamente.

Componentes do Scheduler

SchedulerController

A classe SchedulerController é a classe principal de controle, agendamento e execução das tarefas. Toda a manipulação das tarefas é realizada através dela.

SchedulerTask

SchedulerTask é a interface que representa a tarefa, suas propriedades e meta informações, não exatamente o código de execução. Normalmente a implementação dessa interface se assemelha à um POJO, ou um VO. Podendo inclusive extender diretamente BISVO para que possa ser persistida no banco de dados diretamente.

FWTask

FWTask é a interface padrão do BISFW para definição de uma tarefa. Mais detalhes na página da própria da interface. A implementação desta interface é o código da execução da tarefa. Note que o código da tarefa pode ficar separado dos atirbutos de definição da tarefa (SchedulerTask). Assim permitimos quando necessário que as informações possam da tarefa possam ser armazenadas em classes mais simples como os VOs, sem acompanhar o código da execução.

Classes Não Visíveis Dentro do EJB
Note que a classe de implementação da SchedulerTask será inicializada pelo SchedulerController por reflexão, e que classes que estejam empacotadas dentro de Jar definidos como EJB ficam invisíveis para classes de fora. Logo, se tentar executar uma tarefa cuja classe esteja empacotada dentro do EJB você terá um ClassNotFoundException.

A recomendação é que a classe que implementa a tarefa esteja dentro do pacote externo ao EJB, como o pacote 'Client'. Mesmo que essa implementação não faça nada além de chamar o método do CRUD dentro do EJB. Mesmo porque a tarefa é iniciada sem nenhum tipo de Transaction. De forma geral, a FWTask é iniciada como uma Thread 'crua'.


Objetos Separados Para Otimização de Recursos
Uma vez agendada, o Scheduler manterá em memória o SchedulerTask e todas as suas propriedades. No entanto a implementação FWTask só será inicializada no momento da execução. Ao termino a instância é descartada e as informações serão salvas no SchedulerTask novamente. Assim manter as implementações da tarefa e dos seus meta-dados separados, principalmente para tarefas que se executam com baixa frequência podem gerar economia de recursos significativas.


Funcionamento

Uma vez implementada a interface SchedulerTask, para colocar a tarefa no SchedullerControler basta passa-la pelo método .processTask(SchedulerTask task). Ao passar a tarefa o Scheduler já processará suas definições e se for o caso já executará a tarefa imediatamente (em caso de estar atrasada e a execução atrasada for permitida), ou ela será agendada para execução futura.

Caso a tarefa defina algum método de repetição, ao fim da execução da tarefa o próprio Scheduler se encarregará de reagendar a tarefa. Ou seja, só é preciso passar a tarefa para o SchedullerController uma única vez. Normalmente na inicialização (deploy) da aplicação.

Caso a tarefa não tenha definições de se repetir, casos de tarefas que são executadas uma única vez, o próprio Scheduler limpará os objetos da memória e descartará tudo para o GC.

IDs Únicos

Cada SchedulerTask deve ter um ID único que identifique a tarefa dentro do SchedulerControler. Normalmente, se as tarefas são persistidas em banco de dados, o ID pode ser a chave primária do banco pois é um valor que já se garante ser único por padrão.

No entanto, se temos tarefas que são criadas de forma dinâmica, ou se só existem em memória, essas tarefas precisam garantir que terão um ID único para identificação.

Uma vez que o SchedulerController gerencia suas tarefas pelo seu ID, ao inserir uma tarefa com o mesmo ID de uma já existente, a anterior será cancelada e eliminada para a alocação da nova.


Para garantir uma geração de IDs sequenciais o SchedulerController tem um método estático chamado .generateID(). Este método gerará IDs negativos sequenciais começando em -1 e seguindo para -2, -3, -4, e assim por diante. A intenção de gerar números negativos como chave é para não dar conflito com chaves eventualmente geradas pelo banco de dados. Desta forma é possível coexistir tanto tarefas persistidas pelo banco, e tenho seu ID gerado pela chave do banco, quando tarefas puramente de memória com IDs gerados dinâmicamente.


Para as tarefas que se utilizarem do recurso do .generateID(), recomendamos que este valor seja salvo em uma constante da classe SchedulerTask, para que a tarefa mantenha o mesmo ID durante todas sua execução. Algo como:

public static final long taskID = SchedulerController.generateID();