Evitando recursão ao ler / gravar uma porta de forma síncrona?

108

Todas as operações portuárias em Rebol 3 são assíncronas. A única maneira que encontro de fazer comunicação síncrona é chamando wait.

Mas o problema com a chamada de espera neste caso é que ela verificará eventos para todas as portas abertas (mesmo se eles não estiverem no bloco de portas passado para espera). Em seguida, eles chamam seus manipuladores de eventos de resposta, mas uma leitura / gravação pode ser feita em um desses manipuladores de eventos. Isso pode resultar em chamadas recursivas para "esperar".

Como faço para contornar isso?

Shixin Zeng
fonte
8
Na verdade, não acho que haja uma solução para isso na implementação do R3 atual, então fui em frente para adicionar um refinamento "/ apenas" para "esperar", com o qual, ele só vai esperar pelas portas fornecidas para "esperar" e, assim, evitar as chamadas recursivas. Veja minha solicitação de pull em: github.com/rebol/rebol/pull/177
Shixin Zeng de
1
Por curiosidade, por que você precisa que seja síncrono?
toadzky,
1
Em muitas situações, a codificação com porta síncrona é muito mais fácil: suponha que você queira enviar um e-mail com um clique em um botão e relatar se for bem-sucedido ou falhar. É muito mais fácil esperar a conclusão antes de fazer qualquer outra coisa.
Shixin Zeng,
1
você absolutamente tem que usar Rebol?
Rivenfall
1
Sim. Na verdade, esta é mais uma questão sobre Rebol 3 do que comunicação síncrona em geral.
Shixin Zeng

Respostas:

1

Por que você não cria uma espécie de função "Buffer" para receber todas as mensagens de entradas assíncronas e processá-las como FIFO (first-in, first-out)?

Desta forma, você pode manter as características Assync de suas portas e processá-las no modo de sincronização.

David BS
fonte
0

nos casos em que há apenas eventos assíncronos e estamos precisando de uma resposta síncrona, inicie um cronômetro ou suspenda por tempo limite, se o manipulador ou o objetivo necessário for atendido, diga verdadeiro, senão falso e certifique-se de que o evento seja cancelado / redefinido para o mesmo se crítico.

mkumar
fonte
0

Acho que há 2 problemas de design (talvez intrínsecos às ferramentas / soluções disponíveis).

  1. Waitestá fazendo muito - it will check events for all open ports. Em um ambiente de som, a espera deve ser implementada apenas onde for necessária: por dispositivo, por porta, por soquete ... Criar interdependências desnecessárias entre recursos compartilhados não pode terminar bem - especialmente sabendo que recursos compartilhados (mesmo sem interdependências) pode criar muitos problemas.

  2. Os manipuladores de eventos podem fazer muito. Um manipulador de eventos deve ser o mais curto possível e deve manipular apenas o evento. Se fizer mais, o manipulador está fazendo muito - especialmente se envolver outros recursos compartilhados. Em muitas situações, o manipulador apenas salva os dados que seriam perdidos de outra forma; e um trabalho assíncrono fará as coisas mais complexas.

virolino
fonte
-1

Você pode apenas usar uma fechadura. Cummunication1 pode definir algum estado de bloqueio global, ou seja, com uma variável (certifique-se de que é thread-safe). locked = true. Então Communication2 pode esperar até que seja desbloqueado.

loop do
    sleep 10ms
    break if not locked
end
locked = true
handle_communication()
Rivenfall
fonte
1
Na verdade, esta é mais uma questão sobre Rebol 3 do que comunicação síncrona em geral.
Shixin Zeng