EventDispatcher-v2

De BIS Wiki
Ir para navegação Ir para pesquisar

O framework disponibiliza um serviço de 'Event Dispatcher' (Despachador de Eventos) que tem a finalidade de centralizar a notificação dos listeners quando um evento ocorrer. Um dispatcher centralizado trás as seguintes vantagens:

  • quando um módulo tem um evento para ser disparado este só precisa notificar o event dispatcher que tal evento ocorreu, e não precisa implementar classes para que os listeners se registrem e gerênciar o disparo para cada um.
  • um listener pode se inscrever para receber notificações de um evento, sem ter que se preocupar se o módulo que gera este evento está atualmente instalado ou não, já que o dispatcher gerenciará isso.
  • o dispatcher manterá os eventos de forma padronizada e coerente entre todos os módulos.


Eventos de Negócio
Note que o Event Dispatcher é uma solução para disparo e tratamento de eventos para a camada de negócio! Eventos da camada de apresentação são pertinentes a sessão do usuário e devem ser tratadas na camada de apresentação! Mesmo que as ações do usuário na camada de apresentação (ou mesmo de integração) possam disparar eventos na camada de negócio através do Event Dispatcher.


Funcionamento

O dispatcher funciona pelo pattern singleton. Sendo único e sendo iniciado pela primeira classe que recuperar sua instância, seja para notificar um evento ou seja para se inscrever para notificações.


Arquitetura e Futuro
O EventDispacher foi projetado para que no futuro ele possa notificar eventos de diversas formas, como por chamada de EJB, JMS, e-mail, etc. A principio a única implementação feita será a chamada através de listeners registrados no singleton. Como o BISERP não tem previsão para ser distribuido em JVMs diferentes, o Singleton oferece todo o suporte necessário sem maiores complicações da arquitetura.


Escutando o Evento

O módulo que desejar receber a notificação deverá se registrar no EventDispatcher inscrevendo uma implementação da interface EventDispatcherListener. Toda vez que o evento ocorrer, todos os listeners serão notificados do evento na mesma ordem em que foram registrados.


Notificação

  • A notificação dos listeners são feitas em série, isto é, a próxima só é feita depois que a atual retornar.
  • Embora as notificações sejam feitas na mesma Thread que gerou o evento nenhuma exceção causada pelos listeners interromperá o aviso dos próximos listener e muito menos causará rollback no evento.
  • Os eventos disparados só serão liberados para os listener quando a execução retornar para o BISFacadeInterceptor que iniciou a transação, mas antes do commit ser realizado. A este ponto, praticamente nada impedirá o commit das alterações
    • Isso quer dizer que o listener já é capaz de encontrar todas as alterações, inclusive as realizadas por outros listeners. No entanto se fizer uma chamada em outra Thread fora da transaction, as alterações não estarão visiveis ainda.


Falhas sem Rollback
Note que mesmo que o listener seja acionado dentro da mesma transação "ainda aberta" e que como suas exceptions serão ignoradas, elas não causam rollback da transação atual!! É necessário avaliar a necessidade de criar uma sub-transaction para a execução do seu código e rollback desse sub-transaction.


Disparando de Eventos

Os eventos podem ser disparados a qualquer momento através dos métodos do EventDispatcher. Atualmente o único método existente é o firePostEventsOnQueue(). Este método coloca a notificação do evento na "fila" para notificar todos os seus listeners.

Uma vez que o método termine e retorne seu processamento até o BISFacadeInterceptor todos os eventos na fila serão disparados, pouco antes do commit. Caso o "retorno" para o BISFacadeInterceptor ocorra em forma de exception, que cause o RollBack da transação, nenhum evento será disparado, já que a nada foi concluído. Evitando que os listeners recebam notificações de eventos que foram desfeitos.

Padrão de ID (nome) dos Eventos

O ID dos eventos deve ser composto pelo ID do plugin gerador do evento + nome do evento. O nome do evento pode ser separado com outro pontos, mas deve conter apenas letras minúsculas sem acento e números.

Por exemplo, o evento disparado pelo módulo BISCore deverá começar com "br.com.biserp.bis.core". Os eventos de cadastro de empresa poderiam ser "br.com.biserp.biscore.companyinsert", "br.com.biserp.biscore.companyupdate", "br.com.biserp.biscore.companydelete", etc..