Calling Graph Procedures
As you've already seen, if you call a Graph Procedure from within another Graph (composition) then Claro will
automatically handle the scheduling for you so that downstream nodes receive the value when it's ready. If you tried
calling a Graph Procedure from the top-level of a file, or from a non-Graph Procedure, then you'll see you receive a
value wrapped in a future<...>
. This is because, as Claro follows the Async pattern for concurrent execution, some
nodes in the Graph Procedure may not be done running yet meaning that the overall Graph result may not be ready either.
For example, the getWatchlist
Graph Procedure defined earlier could be
called as if it were a typical procedure call:
Fig 1:
var someUserId: UserId = "Jake";
var graphRes: future<Watchlist> = getWatchlist(someUserId);
There's not much you can do with a future<...>
as it's really just a handle representing work whose result you'd like
to be able to access when it's ready. In this situation (outside a Graph), as a future<...>
represents some
computation that may not be done yet, the only way to get the actual result is to block the current thread until the
other threads running the graph backing the future<...>
have finished. To do so, use the "blocking unwrap" op <-|
:
Fig 2:
var someUserId: UserId = "Jake";
var graphRes: Watchlist <-| getWatchlist(someUserId);
print(graphRes);
Output:
Watchlist([{name = Arrival}, {name = Doctor Who, episodeCount = 1000}])
Graphs Execute off the "Main" Thread
The number one thing to keep in mind is that between calling a Graph and blocking on its result, any operations between
may be running concurrently with the graph backing the future<...>
(you don't know when the graph actually finishes
except that it will certainly have finished after the <-|
operation).
Fig 3:
var graphFuture: future<Foo> = fooGraph(...);
# These two instructions are likely running concurrently with respect to
# `graphFuture`, as `graphFuture` likely hasn't finished yet, but they are
# definitely serialized with respect to each other.
doSomething(...);
doAnotherThing(...);
# Blocking the current thread to "unwrap" the `future<Foo>` into a raw `Foo`
# value we can operate on.
var graphRes: Foo <-| graphFuture;