Next: Transactions make errors survivable, Previous: Objects which contain objects, Up: Tutorial [Contents]
We have shown that the behavior of objects may be invoked
synchronously with $
. However, this only works if two objects
are both defined on the same machine on the network and the same event
loop within that machine.
Now, recall our friend alice
who we defined on vat A. The
following works just fine if we’re still executing within
a-vat
’s subrepl context:
goblins[1]> ($ alice "Alfred") => "Hello Alfred, my name is Alice!"
But let’s exit the a-vat
subrepl and make b-vat
and
enter that:
goblins[1]> ,q scheme> (define b-vat (spawn-vat)) scheme> ,enter-vat b-vat goblins[1]>
But since Alice works on A, we cannot synchronously invoke her with
$
on vat B:
goblins[1]> ($ alice "Bob") ;; === Caught error: === ;; message: #<<message> to: #<local-object> resolve-me: #f args: ()> ;; exception: ... "Not in the same vat:" #<local-object ^greeter>) ...
This is where <-
comes in. In contrast to $
, <-
can be used against objects which live anywhere, even on remote
machines. However, unlike invocation with $
, we do not get
back an immediate result, we get a promise:
goblins[1]> (<- alice "Bob") ; => #<promise>
This promise must be listened to. The procedure to listen to promises
in Goblins is called on
:
goblins[1]> (on (<- alice "Bob") (lambda (got-back) (format #t "Heard back: ~a\n" got-back))) ; Prints out, at some point in the future: ; "Heard back: [3] Hello Bob, my name is Alice!"
Not all communication goes as planned, especially in a distributed
system. Consider an object which breaks in the middle of execution,
such as an instance of ^broken
here:
(define (^broken _bcom) (lambda () (error "Yikes, I broke!")))
on
also supports the keyword arguments of #:catch
and
#:finally
, which both accept a procedure defining handling
errors in the former case and code which will run regardless of
successful resolution or failure in the latter case:
goblins[1]> (define broken-ben (spawn ^broken-ben)) goblins[1]> (on (<- broken-ben) (lambda (what-did-ben-say) (format #t "Ben says: ~a\n" what-did-ben-say)) #:catch (lambda (err) (format #t "Got an error: ~a\n" err)) #:finally (lambda () (display "Whew, it's over!\n")))
Next: Transactions make errors survivable, Previous: Objects which contain objects, Up: Tutorial [Contents]