Os nós de processamento de mensagem e os analisadores devem trabalhar em um ambiente de instâncias múltiplas e encadeamentos múltiplos. Podem existir muitos objetos de nó ou de analisador, cada um deles com muitos elementos de sintaxe, e podem existir muitos encadeamentos executando métodos nesses objetos. O design do intermediário de mensagem assegura que um objeto de mensagem e quaisquer objetos pertencentes a ele sejam utilizados somente pelo encadeamento que recebe e processa a mensagem através do fluxo de mensagens.
Uma instância de um nó de processamento de fluxo de mensagens é compartilhada e utilizada por todos os encadeamentos que servem ao fluxo de mensagens no qual o nó está definido. Para analisadores, uma instância de um analisador é utilizada somente por um único encadeamento de fluxo de mensagens.
Uma extensão definida pelo usuário deve respeitar esse modelo, e deve evitar o uso de dados ou recursos globais que exijam semáforos para serializar o acesso através de encadeamentos. Tal serialização pode resultar em gargalos de desempenho.
As funções de implementação de extensões definidas pelo usuário, e quaisquer funções chamadas por ela, devem ser reentrantes. Todas as funções utilitárias de extensões definidas pelo usuário são completamente reentrantes.
Embora uma extensão definida pelo usuário possa criar encadeamentos adicionais se necessário, é essencial que o mesmo encadeamento retorne o controle ao intermediário na conclusão de uma função de implementação.Se isso não ocorrer a integridade do intermediário será comprometida e resultados imprevisíveis serão produzidos.
O exemplo de fluxo de mensagens a seguir o ajudará a compreender algumas das considerações sobre encadeamentos das quais você deve estar ciente ao projetar e implementar seus próprios nós definidos pelo usuário. Ele considera o exemplo de um nó input definido pelo usuário.
Um fluxo de mensagens pode ser configurado para executar em um conjunto de encadeamentos. Isso é determinado pelo número de nós de entrada no fluxo de mensagens e pelo valor da propriedade additionalInstances do fluxo de mensagens. Esses dois elementos determinam a capacidade máxima do conjunto de encadeamentos que o fluxo de mensagens pode utilizar. Portanto, se seu fluxo de mensagens tiver requisitos específicos de processamento que ditem a execução com um único encadeamento, você precisa assegurar que seja esse o caso.
Permitir que o intermediário inicie cópias adicionais do fluxo de mensagens em encadeamentos separados utilizando a propriedade additionalInstances é a maneira mais eficiente de evitar que a fila de entrada se torne um gargalo. Contudo, a criação de encadeamentos separados permite o processamento paralelo de mensagens da fila de mensagens, e por isso essa propriedade deve ser utilizada somente quando a ordem em que as mensagens são processadas não for importante.
Os encadeamentos são criados como resultado da construção e operação do nó input. Um encadeamento permanece ativo ou inativo no conjunto de encadeamentos, e os encadeamentos inativos permanecem no conjunto até que sejam despachados por um nó input ou que o intermediário seja encerrado.
A figure a seguir ilustra a alocação de encadeamentos em um fluxo de mensagens.
Alocação de encadeamentos em um fluxo de mensagens
Inicialmente, Encadeamento 1 é requerido (A) e aguarda mensagens. Quando uma mensagem chega (B), Encadeamento 1 propaga a mensagem e despacha Encadeamento 2. Encadeamento 2 recebe uma mensagem imediatamente (C) e propaga e despacha Encadeamento 3, que aguarda uma mensagem (D). Encadeamento 1 conclui (E) e retorna ao conjunto de encadeamentos. Encadeamento 3 recebe então uma mensagem (F), despacha Encadeamento 1 e propaga a mensagem. Encadeamento 1 agora aguarda que uma mensagem chegue na fila (G).
Vale a pena observar o ponto marcado como H. Nesta instância no fluxo de mensagens, Encadeamento 1 adquire uma mensagem, mas como todos os outros encadeamentos estão ativos nesse momento, ele não pode despachar. A mensagem é propagada.
Depois que essa mensagem é propagada, Encadeamento 2 conclui (I), recebe uma nova mensagem da fila e propaga essa nova mensagem. Encadeamento 3 então conclui (J) e retorna ao conjunto. Encadeamento 2 então também é concluída (K). Como ele não despachou, quando Encadeamento 1 foi concluída (L) ele não pode retornar ao conjunto de encadeamentos embora não existam mensagens na fila, e em vez disso aguarda que uma mensagem chegue na fila.