Next: Transactions make errors survivable, Previous: Objects which contain objects, Up: Tutorial [Contents][Index]
You have seen 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 your friend alice
who you defined on vat A. The
following works just fine if you’re still executing within
a-vat
’s subrepl context:
goblins[1]> ($ alice "Alfred") => "Hello Alfred, my name is Alice!"
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]>
Since Alice works on A, you 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 $
, you do not get
back an immediate result; you 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)) 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][Index]