Pergunta

Insatisfeito com a minha abordagem atual, eu só estou tentando reformular a maneira que eu construir pilhas de protocolo em Erlang.O recurso ordenadas por importância:

  1. Desempenho

  2. A flexibilidade e a velocidade da implementação de adicionar novas variantes de protocolo

  3. Gostaria de ajudar de desenvolvimento para explorar as variantes de protocolo, a partir da shell

O meu modelo atual (quealreday descrita nesta pergunta) está chegando ao seu limite, além de feio assimetria de enviar() pela chamada de função e receber por mensagem.

O quadro geral de todo o mecanismo do protocolo parecido com este:

Parte inferior:

  • Existem vários portos ou talvez, também, por vezes, um gen_tcp na parte inferior de cada pilha (existem vários idênticos pilhas para canais independentes, de modo que não pode ser demasiado estático aqui apenas registrar processos, tem que passar Pids em todos os lugares.

  • Na parte superior das portas são alguns módulos que são gerenciados pelo supervisor (iniciado com o sistema, e na ausência de erros ficar a vida toda).

Parte superior:

  • Desencadeada pela ocorrência do evento (no sentido geral, não no event_handler sentido) são orientados para a conexão de protocolo termina (por exemplo,com connect() e close() semântica.

  • A extremidade superior da pilha de protocolo pode, provavelmente, ser iniciado somente dinamicamente porque os módulos empilhados um em cima do outro para formar a pilha de são dinamicamente configurável e pode mudar de conexão para a conexão.

  • Actualmente planeado estaria passando uma Lista de nomes de módulo + opcional de parâmetros de nível superior que obter consumida enquanto connect() é chamado para baixo da pilha.

  • De nível superior os processos serão ligados por isso, quando alguma coisa der errado aqui toda a conexão falhar.

Tipos de módulos e tipos de comunicação entre eles

Existem vários tipos de módulos encontrados até o momento:

  • Sem monitoração de estado módulos de filtro de

  • Módulos com o estado, alguns ajuste gen_server, alguns gen_fsm mas a maioria provavelmente vai ser simples servidor de loops, pois seletiva receber vai ser útil e simplificar o código, muitas vezes.

Tipos de comunicação entre as camadas:

  • Independente de envio e recebimento de pacotes (independente, como visto a partir do lado de fora)

  • Chamadas síncronas que enviar algo, bloco até que haja uma resposta e, em seguida, retornar o resultado como valor de retorno.

  • Multiplexadores que falar para baixo para vários módulos (isso é a minha definição aqui para facilitar a discussão)

  • Demultiplexers que têm diferentes pontos de fixação (chamado por átomos atualmente) para falar com voltadas para cima módulos.

Atualmente só meu demultiplexers estão na estatístico parte inferior da pilha e não criado dinamicamente parte superior.Os multiplexadores são apenas na parte superior atualmente.

As respostas e comentários do meu vinculada pergunta anterior manuseio eu ouvi que, geralmente, a API deve consistir apenas de funções e não as mensagens e eu concordo com isso, a menos convencido do contrário.

Por favor, desculpem a longa explicação do problema, mas eu acho que ainda é de uso geral para todos os tipos de implementação do protocolo.

Vou escrever o que eu tenho planejado até agora as respostas e também vai explicar também a resultante de implementação e a minha experiência com ele mais tarde, a fim de alcançar algo que normalmente é útil, aqui.

Foi útil?

Solução

Eu vou jogar o que eu tenho planejado para longe, como parte das respostas:

  • conectar é passada uma Lista de módulos a pilha, parecendo um proplist em caso de parâmetros e.g:

    connect([module1, module2, {module3, [params3]}], param0, further_params)
    

    cada camada de tiras de fora a cabeça e chama o próximo camadas ligar.

  • connect() "de alguma forma" passa de diversão referências e/ou as camadas

    • enviar para envio assíncrono para baixo da pilha será devolvido pelo menor nível de conectar-se
    • recv para assíncrono de receber a pilha vai ser passado como parâmetro para o menor nível de conectar-se
    • chamada para sincronizar o envio de e esperando por uma resposta devolvidos -- não tem a certeza de como lidar com esses, provavelmente, também retornou de nível inferior se conectar
  • Multiplexadores de encaminhamento de listas podem olhar como esses

    connect([module1, multiplexer, [[m_a_1, m_a_2, {m_a_3, [param_a_3]}], 
                                    [m_b_1, m_b_2],
                                    [{m_c_1, [param_c_1]}, m_c_2]], param0, 
                                                                    further_params]).
    

Atualmente eu decidi não ser uma função extra para chamadas síncronas, eu só estou usando o enviar para ele.

Há um exemplo de uma implementação da ideia, neste caso, para um módulo que é stateless: encode/1 e decode/1 fazer alguns para e de volta transformação em pacotes e.g.analisar a representação binária em um registro e volta:

connect(Chan, [Down|Rest], [], Recv_fun) ->
    {Down_module, Param} = case Down of
                               {F, P} -> {F, P};
                               F when is_atom (F) -> {F, []}
                           end,
    Send_fun = Down_module:connect(Chan, Rest, Param,
                                   fun(Packet) -> recv(Packet, Recv_fun) end),
    {ok, fun(Packet) -> send(Packet, Send_fun) end}.

send(Packet, Send_fun) ->
    Send_fun(encode(Packet)).

recv(Packet, Recv_fun) ->
    Recv_fun(decode(Packet)).

Assim que eu tiver um stateful exemplo vou postar também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top