Participamos de um desafio 12c que tinha muitos sabores diferentes (BPM, coerência, ADF, etc) e alguns requisitos muito rigorosos de desempenho.
Cenário
Nesta solução, um operador seria conectado a um aplicativo do ADF mostrando as diferentes regiões, com uma região específica que precisaria atualizar com a instância BPM e evoluir através de diferentes tarefas humanas no processo. A equipe tinha optado por uma solução simples para saber quando uma instância BPM tinham atingido uma tarefa humana: para sondar o motor até que uma tarefa fosse encontrada.
Quer saber mais? Entre em contato com a HTI!
O problema
A eleição do motor poderia ser uma solução se a carga da instância fosse baixa, mas o objetivo era o de lidar com milhares de casos de curta duração em paralelo, o que sobrecarrega o motor com consultas. Além disso, houve o problema de ter que esperar um intervalo que resultou na perda de tempo adicional.
Tal como acontece com a maioria dos casos push/pull, o ideal seria abordar o problema do outro lado da cerca: em vez de sondagem de eventos, empurrando os processo BPMN e reagir a estas a partir da UI.
Para a primeira parte, emitindo eventos quando as tarefas BPM chega a uma tarefa humana seria simples e direta: a API de fluxo de trabalho humano fornece uma série de retorno de eventos que podem ser utilizadas, com o evento sendo uma onAssigned para uso. Portanto, a pergunta restante foi como receber e processa eventos no lado ADF.
A solução
A partir dos requisitos, precisávamos de uma forma de reagir quando um evento fosse recebido. E conduzir imediatamente usando JavaScript, que é bem suportado no ADF. A única questão que ficou, foi que tipo de evento a receber.
A resposta está em um novo recurso "nativo" Weblogic 12c : web-sockets (podemos usar web-sockets em 11g usando Jersey também). JavaScript pode lidar com a abertura de novas bases e ouvir as mensagens.
Foi desenvolvido um aplicativo de Web Socket que permitisse um ponto de extremidade do servidor para cada instância BPM (lembre-se estes são casos de curta duração, portanto, não há risco de ficar sem recursos).
Como o aplicativo ADF foi responsável pela criação de instâncias de BPM com uma chave de correlação, é conectado ao terminal do servidor usando essa mesma chave, estabelecendo efetivamente uma conexão direta do ponto final com o seu próprio canal.
No lado do servidor, cada evento onAssigned que seriam recebidos pela classe de retorno de tarefa humana irá publicar uma nova mensagem para o terminal (usando a mesma chave de correlação, neste caso exposto como um atributo público na tarefa humana), que por sua vez, seria retransmitida pelo servidor para a interface do usuário ADF.
Melhorado Mais
Logo descobrimos que nós nem sequer precisamos esperar o evento OnAssigned: usando uma API REST (12c pode chamar diretamente os serviços REST) que poderia permitir que o processo para notificar o UI o mais rapidamente possível, portanto, encurtando os tempos ainda mais. Assim, dois eventos foram enviados para a interface do usuário: um para notificar que os dados estava disponível e o segundo para ativar os botões da interface do usuário para processamento. No momento em que o usuário tinha lido as informações exibidas na página, os botões já seriam habilitados.
O desempenho que foi melhorado cerca de 40% beneficiou-se de:
Removendo o mecanismo de pesquisa, eliminando assim o acesso backend para o banco de dados e o intervalo de espera
Acessar e exibir os dados na interface do usuário final logo que estava disponível
Usando o "Time Thinking" do usuário para permitir o processo para executar operações adicionais.
E por último, mas não menos importante, podemos pensar em um caso de uso adicional muito simples para web-sockets: usá-los na aplicação do espaço de trabalho para notificar quando um usuário conectado tem uma nova tarefa adicional. Nós certamente vamos implementar este recurso em nosso espaço de trabalho personalizado - mas isso será deixado para outro artigo.