Next: , Previous: , Up: Vats   [Contents][Index]


5.2.2 Making vats

At a high level, users generally will spawn a vat, bind it to a name in the local namespace, and use it for various operations. This will usually use spawn-vat:

Procedure: spawn-vat [#:name] [#:log?] [log-capacity]

Create and return a reference to a new vat.

  • name: Name of the vat. Note that this is not the name it is bound to in the current namespace.
  • log?: If #t, log vat events; otherwise, do not.
  • log-capacity: Number of events to be retained in the log. Defaults to 256.
(define a-vat (spawn-vat))

Sometimes, it is useful to make and manage a vat at a slightly lower level, such as when using Goblins with a foreign event loop (like a GUI toolkit or game engine). In such cases, make-vat comes into play:

Procedure: make-vat [#:name] [#:start] [#:halt] [#:send] [#:log?] [log-capacity]

Return a new vat named name. Vat behavior is determined by three event hooks, and logging is controlled by the remaining arguments:

  • start: Procedure to start vat process in non-blocking manner such as a new thread. Accepts a procedure which takes a message as its single argument and churns the underlying actormap for the vat.
  • halt: Thunk to stop vat process.
  • send: Procedure accepting a “vat envelope” containing a message to handle within the vat process. The envelope also indicates if the caller wants a response, in which case the send procedure must block until the message has been processed and return the result.
  • log?: If #t, event logging is enabled, otherwise it is disabled (the default).
  • log-capacity: Number of events to be retained in the log. Defaults to 256.

Here is a pseudocode example illustrating the basic pattern:

(define (make-custom-vat)
  (define thread #f)
  (define (start churn)
    (define (loop)
      (churn (dequeue-msg))
      (loop))
    (set! thread (call-with-new-thread loop)))
  (define (halt)
    (cancel-thread thread))
  (define (send envelope)
    (if (vat-envelope-return? envelope)
        (enqueue-and-wait-for-result envelope)
        (enqueue envelope)))
  (make-vat #:start start
            #:halt halt
            #:send send))

How to implement enqueue-msg, enqueue-and-wait-for-result, and dequeue depends on the integration target and is left as an exercise for the implementer.

Custom vat implementations must enqueue and dequeue messages in a thread-safe manner because incoming messages from other vats may be, and likely are, running in a different thread.

The above custom vat would be used like so:

> (define custom-vat (make-custom-vat))
> (vat-start! custom-vat)

Custom vats are expected to handle “vat envelope” objects which contain a message, a logical timestamp, and a flag indicating if the sender wants to know the result of processing the message.

Procedure: vat-envelope? obj

Return #t if obj is a vat envelope, or #f otherwise.

Procedure: vat-envelope-message envelope

Return the message contained in envelope.

Procedure: vat-envelope-timestamp envelope

Return the logical timestamp for envelope. This timestamp indicates when envelope was sent from its origin vat.

Procedure: vat-envelope-return? envelope

Return #t if the result of processing the message within envelope should be returned to the caller who deposited the envelope, or #f otherwise. When #t, a custom vat implementation must block until a result can be returned to the caller. Notably, call-with-vat relies upon this behavior.


Next: Using vats, Previous: Vats overview, Up: Vats   [Contents][Index]