¿Evita la recursividad al leer / escribir un puerto sincrónicamente?

108

Todas las operaciones portuarias en Rebol 3 son asincrónicas. La única forma que puedo encontrar para hacer una comunicación sincrónica es llamando wait.

Pero el problema de llamar a esperar en este caso es que verificará los eventos para todos los puertos abiertos (incluso si no están en el bloque de puertos pasado a esperar). Luego llaman a los controladores de eventos que responden, pero se podría realizar una lectura / escritura en uno de esos controladores de eventos. Eso podría resultar en llamadas recursivas a "esperar".

¿Cómo puedo solucionar esto?

Shixin Zeng
fuente
8
En realidad, no creo que haya una solución para esto en la implementación actual de R3, así que seguí adelante para agregar un refinamiento "/ solo" a "esperar", con lo cual, solo esperará en los puertos provistos para "esperar" , y así evitar las llamadas recursivas. Vea mi solicitud de extracción en: github.com/rebol/rebol/pull/177
Shixin Zeng
1
Por curiosidad, ¿por qué necesita que sea sincrónico?
Toadzky
1
Hay muchas situaciones en las que la codificación con puerto síncrono es mucho más fácil: suponga que desea enviar un correo electrónico con un clic en un botón e informar si tiene éxito o falla. Es mucho más fácil esperar a que termine antes de hacer cualquier otra cosa.
Shixin Zeng
1
¿Es absolutamente necesario utilizar Rebol?
Rivenfall
1
Si. En realidad, se trata más de una pregunta sobre Rebol 3 que sobre la comunicación síncrona en general.
Shixin Zeng

Respuestas:

1

¿Por qué no crea una especie de función "Buffer" para recibir todos los mensajes de entradas asociadas y procesarlos como FIFO (primero en entrar, primero en salir)?

De esta manera, puede mantener las características Assync de sus puertos y procesarlas en modo de sincronización.

David BS
fuente
0

en los casos en que solo hay eventos asincrónicos y necesitamos una respuesta sincrónica, inicie un temporizador o suspenda el tiempo de espera, si se cumple el controlador o el objetivo requerido, diga verdadero, de lo contrario falso y asegúrese de que el evento se cancele / reinicie para el lo mismo si es crítico.

mkumar
fuente
0

Creo que hay 2 problemas de diseño (quizás intrínsecos a las herramientas / soluciones disponibles).

  1. Waitestá haciendo demasiado - it will check events for all open ports. En un entorno sólido, la espera debe implementarse solo donde sea necesario: por dispositivo, por puerto, por socket ... La creación de interdependencias innecesarias entre recursos compartidos no puede terminar bien, especialmente sabiendo que los recursos compartidos (incluso sin interdependencias) puede crear muchos problemas.

  2. Los controladores de eventos pueden hacer demasiado. Un controlador de eventos debe ser lo más corto posible y solo debe manejar el evento. Si hace más, entonces el controlador está haciendo demasiado, especialmente si involucra otros recursos compartidos. En muchas situaciones, el manejador simplemente guarda los datos que de otro modo se perderían; y un trabajo asincrónico hará las cosas más complejas.

virolino
fuente
-1

Puedes usar un candado. Cummunication1 puede establecer algún estado de bloqueo global, es decir, con una variable (asegúrese de que sea seguro para subprocesos). locked = true. Entonces Communication2 puede esperar hasta que se desbloquee.

loop do
    sleep 10ms
    break if not locked
end
locked = true
handle_communication()
Rivenfall
fuente
1
En realidad, se trata más de una pregunta sobre Rebol 3 que sobre la comunicación síncrona en general.
Shixin Zeng