Getting Started Documentation Glish Learn More Programming Contact Us
Version 1.9 Build 1556
News FAQ
Search Home


next up previous contents index
Next: Memory Usage Up: Predefined Functions and Variables Previous: Manipulating Variable Argument Lists


Manipulating Agents

Glish provides the following functions for manipulating agent values:

create_agent()
returns a new agent value that can be used in subsequent whenever and send statements. That is, the agent value can be sent events and you can set up whenever's to deal with receiving these events.

For example,

    a := create_agent()
    a->hi( "how are you?" )

    whenever a->hi do
        print $value
prints "how are you?". I am interested in hearing if you find create_agent() itself more useful than using subsequences (§ 7.12, page [*]), which provides a more structured interface to dealing with agent's.

client(command,
..., host=F, input=F, suspend=F, ping=F, async=F) creates a Glish client corresponding to the given command and arguments. (See § 7.8.1, page [*], for details.)

shell(command,
..., host=F, input=F, suspend=F, ping=F, async=F) either executes a Bourne shell command and returns a string representation of its output (if async=F), or creates an asynchronous shell client that can be sent stdin and EOF events and that in turn generates stdout events. The first of these is discussed in § 4.10, page [*], and the second in § 7.8.2, page [*].

sync(c)
synchronizes the Glish script's execution with that of client c. The call to sync() does not return until client c has processed all events/requests previously sent to it.

relay(src,
src_name, ref dest, dest_name="*") relays every src_name generated by the agent src to the agent dest, renaming the event to dest_name. If dest_name is "*" (the default) then src_name is used.

For example,

    relay(a, "ready", b, "compute")
relays each of a's ready events to b, renaming them compute, and
    relay(a, "ready", b)
relays ready events generated by a to b, keeping the event's name.

relay_all(src, ref dest)
relays every event from src to dest; it is equivalent to:
    whenever src->* do
        dest->[$name]($value)

birelay_event(ref
agent1, ref agent2, name) relays any ``name" event generated by either agent1 or agent2 to the other agent. Thus it is equivalent to:
    relay( agent1, name, agent2 )
    relay( agent2, name, agent1 )

birelay_all(ref
agent1, ref agent2) relays every event generated by either agent1 or agent2 to the other agent. It is equivalent to:
    relay_all( agent1, agent2 )
    relay_all( agent2, agent1 )

bundle_events(a,size)
causes events sent to a to be queued. The size argument is optional. If it is supplied, the bundled events are sent after their total size exceeds size, otherwise all of the bundled events are written at once when flush_events() is called. This can sometimes be useful if many small events are being sent to a client, and the delay seems to long. Often the best way to fix this problem is to alter the client's event interface, but this provides a quick way to see what sort of performance gain is possible.

flush_events(a)
causes all events which have been bundled for the client a but not yet sent to be sent to the client. This also clears the event bundling so that no more events will be bundled until the next call to bundle_events().

current_whenever()
returns an index identifying the whenever statement whose body is currently (or was last) executed in response to an event. This index has type integer and is suitable for use in an activate or deactivate statement (§ 7.5.4, page [*]) for controlling the activity of the whenever statement.

For example, suppose that client a generates both b and c events, and you want to respond to b events only as long as you haven't received a c event. You use the following:

    whenever a->b do
        {
        do_b_stuff()
        w := current_whenever()
        }

    whenever a->c do
        {
        do_c_stuff()
        deactivate w    # turn off a->b
        }
This example actually has a bug: if a generates a c event before any b events, then w is not defined when executing the deactivate statement, resulting in an error. (See the discussion of last_whenever_executed() below for a bug-free example.)

last_whenever_executed()
returns an index identifying the most recently-executed whenever statement. Here, ``executed'' refers to execution of the whenever statement itself (which ``activates'' the whenever), and not its body.

As with current_whenever(), this index has type integer and is suitable for use in an activate or deactivate statement (§ 7.5.4, page [*]). The example used above in describing current_whenever() can instead be written as:

    whenever a->b do
        {
        do_b_stuff()
        }

    w := last_whenever_executed()

    whenever a->c do
        {
        do_c_stuff()
        deactivate w    # turn off a->b
        }

active_agents()
returns a record array listing the currently active agents. For example, the following:
    agents := active_agents()

    for ( i in 1:len(agents) )
        {
        a := ref agents[i]
        if ( has_field(a, "locked") )
            a->clear_lock()
        }
sends a clear_lock event to each agent whose agent record has a locked field (presumably due to a previously-received locked event).

Note that the system global variable (§ 10.11, page [*]) is an agent, so active_agents() ordinarily returns at least one agent.

whenever_active(index)
returns T if the whenever statement identified by index is active. The index is from last_whenever_executed() or current_whenever() above.

whenever_stmts(agent)
returns a record identifying the event names, corresponding whenever statements associated with agent, and which of the statements are currently active as a result of activate or deactivate statements. The record has three fields, event, stmt and active, which are string, integer and boolean vectors, respectively. For example,
    a := create_agent()
    whenever a->foo do print 1
    whenever a->bar do print 2
    b := whenever_stmts(a)
assigns to b a record whose event field corresponds to the string vector "foo bar", whose stmt field holds as its first and second elements the indices of the first and second whenever statements, and whose active field holds two T values.

The following, for example, turns off every whenever statement associated with some agent's ``warning'' event:

    agents := active_agents()

    for ( i in 1:len(agents) )
        {
        a := ref agents[i]
        w := whenever_stmts(a)
        mask := w.event == "warning"
        deactivate w.stmt[mask]
        }


next up previous contents index
Next: Memory Usage Up: Predefined Functions and Variables Previous: Manipulating Variable Argument Lists   Contents   Index
Please send questions or comments about AIPS++ to aips2-request@nrao.edu.
Copyright © 1995-2000 Associated Universities Inc., Washington, D.C.

Return to AIPS++ Home Page
2006-10-15