Getting Started | Documentation | Glish | Learn More | Programming | Contact Us |
Version 1.9 Build 1556 |
|
As discussed in § 5.10.2, the await statements comes in three forms:
await event1, event2, ...
await only event1, event2, ...
await only event1, event2, ... except event1, event2, ...In each of these forms, event designates an event just like in a whenever statement.
An await statement instructs Glish to wait for one of the listed events to occur. Glish pauses program execution until this happens. Without the only keyword, Glish will still process incoming events by executing their corresponding whenever bodies. This style of await can be used to effect synchronous communication with an agent. For example, suppose that c refers to a client that when sent a compute request performs some computation and generates a compute_done event when finished. If you want to tell c's client to do its computation and wait for the result, you do the following:
c->compute() await c->compute_done # at this point, c is done # with its computationAfter an await completes, $agent, $name, and $value correspond to the event that caused the await to finish. In the above example, $agent will be c, $name will be "compute_done", and $value will be the value of the compute_done event. In general, though, this is probably better written as:
result := c->compute()This version is more concise and more efficient.
If you use the only keyword then while Glish is waiting for one of the listed events, no intervening events it receives will be processed. Instead, these events are ``dropped"; it is as though they had never occurred, though Glish generates a warning message concerning each dropped event.
The await only statement is meant for use as a ``hold-point", to freeze the effective execution of a Glish program until some seminal event occurs. For example, suppose that when key_program generates a panic event that it is vital to suspend execution of the Glish program and its clients until the current program state can be archived by the archiver client. You might program this using:
whenever key_program->panic do { print "panic, doing archive snapshot" archiver->do_archive await only archiver->archive_done }
Sometimes during such an await only there are a few events that if they arrive still must be processed. Glish provides for this case with the await only ... except statement. If in the above example you also have a high_priority client that has to continue even during the archiving, you can use:
whenever key_program->panic do { print "panic, doing archive snapshot" archiver->do_archive await only archiver->archive_done except high_priority->* }Similarly, you can restrict which of high_priority's events were processed during archiving by replacing the * event name with a specific event name or list of names:
whenever key_program->panic do { print "panic, doing archive snapshot" archiver->do_archive await only archiver->archive_done except high_priority->interrupt }
Since in general when executing an await other events may be processed, leading to the execution of the body of whenever statements, the question arises ``What happens if one of those whenever bodies itself executes an await?" We call such an await within another await a nested await.
Only the most recently executed nested await is active, i.e. execution is stopped until that await gets its event. But all of the awaits that are queued up will get their value in the order that they started waiting. Lets look at an example:
c1 := client("c1") c2 := client("c2") whenever c1->ready do { c2->doit() await c2->done } whenever c2->ready do { c1->doit() await c1->done }if c1 generates a ready event you send a doit event to c2 and then enter an await waiting for c2 to generate done. If c2 then first generates ready prior to generating done then you execute the second whenever clause, resulting in sending a doit event to c1 and then a nested await as you wait for c1 to generate done.
If c1 now generates done then you go back to waiting for c2 to generate done. But what happens if c2 generates a done event before c1? In this case, the done event from c2 is held for the await pending for c2 until a done event is received from c1. So where awaits are concerned, the events are processed in the order forced by the script rather than the order the events were received.
There can even be cases where two awaits are waiting for the same event from the same client. In this case, the first await gets the first event coming from the client. The second await must continue to wait for the next event of the specified type. This is typically what is desired because the agent probably processes the first event it recieves and generates a result before starting on the second event.