108

All port operations in Rebol 3 are asynchronous. The only way I can find to do synchronous communication is calling wait.

But the problem with calling wait in this case is that it will check events for all open ports (even if they are not in the port block passed to wait). Then they call their responding event handlers, but a read/write could be done in one of those event handlers. That could result in recursive calls to "wait".

How do I get around this?

Shixin Zeng
  • 1,458
  • 1
  • 10
  • 14
  • 8
    Actually, I don't think there is a solution to this in current R3 implementation, so I went ahead to add a "/only" refinement to "wait", with which, it will only wait on the ports provided to "wait", and thus avoid the recursive calls. See my pull request at: https://github.com/rebol/rebol/pull/177 – Shixin Zeng Feb 16 '14 at 16:51
  • 1
    Out of curiousity, why do you need it to be synchronous? – toadzky Mar 09 '15 at 13:49
  • 1
    There are a lot of situations that coding with synchronous port is much easier: suppose you want to send an email with a click on a button, and report if it succeeds or fails. It's much easier to wait for it to be finished before doing anything else. – Shixin Zeng Mar 09 '15 at 14:40
  • 1
    do you absolutely have to use Rebol? – Rivenfall May 17 '15 at 11:32
  • 1
    Yes. This is actually more a question about Rebol 3 than synchronous communication in general. – Shixin Zeng May 18 '15 at 18:12
  • Please tell us if you can modify / rewrite the `wait` function? I expect that you can modify the `handlers`, am I right? I do not have experience with your particular environment. – virolino Feb 06 '19 at 06:40

4 Answers4

1

Why don´t you create a kind of "Buffer" function to receive all messages from assyncronous entries and process them as FIFO (first-in, first-out)?

This way you may keep the Assync characteristics of your ports and process them in sync mode.

David BS
  • 1,822
  • 1
  • 19
  • 35
0

in cases where there are only asynchronous events and we are in need on synchronous reply, start a timer or sleep for timeout, if the handler or required objective is met then say true, else false and make sure the event gets cancelled /reset for the same if critical.

mkumar
  • 111
  • 1
  • 10
0

I think that there are 2 design problems (maybe intrinsic to the tools / solutions at hand).

  1. Wait is doing too much - it will check events for all open ports. In a sound environment, waiting should be implemented only where it is needed: per device, per port, per socket... Creating unnecessary inter-dependencies between shared resources cannot end well - especially knowing that shared resources (even without inter-dependencies) can create a lot of problems.

  2. The event handlers may do too much. An event handler should be as short as possible, and it should only handle the event. If is does more, then the handler is doing too much - especially if involves other shared resources. In many situations, the handler just saves the data which will be lost otherwise; and an asynchronous job will do the more complex things.

virolino
  • 2,073
  • 5
  • 21
-1

You can just use a lock. Cummunication1 can set some global lock state i.e. with a variable (be sure that it's thread safe). locked = true. Then Communication2 can wait until it's unlocked.

loop do
    sleep 10ms
    break if not locked
end
locked = true
handle_communication()
Rivenfall
  • 1,189
  • 10
  • 15