co.paralleluniverse.pulsar.actors

Defines actors and behaviors like gen-server and supervisor

!

macro

(! actor message)(! actor arg & args)
Sends a message to an actor.
This function returns `nil`.
If the actor's mailbox capacity has been exceeded, this function's behavior
is determined by the `overflow-policy` set by the receiving actor's `spawn`.

See: `spawn`

!!

macro

(!! actor message)(!! actor arg & args)
Sends a message to an actor synchronously.
This has the exact same semantics as !, but hints to the scheduler that the
current actor is about to wait for a response from the message's addressee.

See: `!`

->Initializer

(->Initializer init terminate)(->Initializer init)

->MailboxConfig

macro

(->MailboxConfig size overflow-policy)

->PulsarEventHandler

(->PulsarEventHandler handler)
Positional factory function for class co.paralleluniverse.pulsar.actors.PulsarEventHandler.

actor

macro

(actor bindings & body)
Creates a new actor.

actor-builder

(actor-builder f & args)

add-child!

(add-child! supervisor id mode max-restarts duration unit shutdown-deadline-millis & args)
Adds an actor to a supervisor

add-handler!

(add-handler! ge handler)

call!

(call! gs m)(call! gs m & args)
Makes a synchronous call to a gen-server and returns the response

call-timed!

(call-timed! gs timeout unit m)(call-timed! gs timeout unit m & args)
Makes a synchronous call to a gen-server and returns the response

capitalize

(capitalize s)

cast!

(cast! gs m)(cast! gs m & args)
Makes an asynchronous call to a gen-server

defactor

macro

(defactor name doc-string? attr-map? [params*] body)
Defines a new actor template.

done?

(done? a)
Tests whether or not an actor has terminated.

gen-event

(gen-event :name? :timeout? :mailbox-size? :overflow-policy? server & args)
Creates (but doesn't start) a new gen-event

gen-fsm

(gen-fsm :name? :mailbox-size? :overflow-policy? initial-state)
Creates (but doesn't start) a new gen-fsm

gen-server

macro

(gen-server :name? :timeout? :mailbox-size? :overflow-policy? server & args)
Creates (but doesn't start) a new gen-server

get-actor

(get-actor a)
If the argument is an actor -- returns it. If not, looks up a registered
actor with the argument as its name.

The name can be a string or a keyword, in which case it's identical to the keyword's name
(i.e. a name of `"foo"` is the same as `:foo`).

get-child

(get-child sup id)
Returns a supervisor's child by id

link!

(link! actor2)(link! actor1 actor2)
Links two actors. If only one actor is specified, links the current actor with the
specified actor.

A link is symmetrical. When two actors are linked, when one of them dies, the other throws
a `co.paralleluniverse.actors.LifecycleException` exception which, unless caught, kills it
as well.
If `:trap true` was added to the actor's `spawn` call, or if `(trap!)` has been called by
the actor, rather than an exception being thrown, an exit message is sent to the actor.
The message is of the same structure as the one sent as a result of `watch!` except that
the watch element is `nil`.

See: `unlink!`, `watch!`

log

macro

(log level message & args)

mailbox

@mailbox is the mailbox channel of the currently running actor

mailbox-of

(mailbox-of actor)
Returns the mailbox of the given actor.

maketag

(maketag)
Returns a random, probably unique, identifier.
(this is similar to Erlang's makeref).

notify!

(notify! ge event)

receive

macro

(receive)(receive patterns* <:after ms action>?)(receive [binding transformation?] patterns* <:after ms action>?)
Receives a message in the current actor and processes it.

Receive performs pattern matching (with free var binding) on the message.
Example:
  (let [actor (spawn
               #(receive
                   :abc "yes!"
                   [:why? answer] answer
                   :else "oy"))]
     (! actor [:why? "because!"])
     (join actor)) ; => "because!"

`receive` performs a *selective receive*. If the next message in the mailbox does
not match any of the patterns (and an `:else` clause is not present), it is skipped,
and the next message will be attempted.
`receive` will block until a matching message arrives, and will return the value of
the matching clause.

Skipped messages are not discarded, but are left in the mailbox. Every call to `receive`
will attempt to match any message in the mailbox, starting with the oldest.
(Skipped messages migh accumulate in the mailbox if not matched, so it's good practice
to at least occasionally call a `receive` that has an `:else` clause.)

If the first element of the `receive` expression is a vector, it is used for binding:
The vector's first element is the name assigned to the entire message, and the second,
if it exists, is a transformation function, of one argument, that will be applied to
the message before binding and before pattern-matching:

   (receive [m transform]
     [:foo val] (println "got foo:" val)
     :else      (println "got" m))

 Now `m` – and the value we're matching – is the the transformed value.

A timeout in milliseconds, may be specified in an `:after` clause, which must appear last:

  (receive [m transform]
     [:foo val] (println "got foo:" val)
     :else      (println "got" m)
     :after 30  (println "nothing..."))

`receive` may be called without parameters, in which case it will indefinitely wait for
the next (without any selection) message and return it. For a non-selective receive with
a timeout, use `timed-receive`.

receive-timed

(receive-timed timeout)
Waits (and returns) for a message for up to timeout ms. If time elapses -- returns nil.

recur-swap

macro

(recur-swap f & args)
Recurs to `f` (which is the actor function), checking for possible hot code swaps
and applying them.

register!

(register! actor-name actor)(register! actor-or-name)(register!)
Registers an actor in the actor registry.
The actor is registered by its name, or, if it doesn't have a name, one must be supplied
to this function. The name can be a string or a keyword, in which case it's identical to the
keyword's name (i.e. a name of `"foo"` is the same as `:foo`).

remove-and-terminate-child!

(remove-and-terminate-child! supervisor id)
Removes an actor from a supervisor and terminates the actor

remove-child!

(remove-child! supervisor id)
Removes an actor from a supervisor

remove-handler!

(remove-handler! ge handler)

reply!

(reply! to id res)
Replies to a message sent to the current gen-server

reply-error!

(reply-error! to id error)
Replies with an error to a message sent to the current gen-server

request!

macro

(request! actor & message)

request-timed!

macro

(request-timed! timeout actor & message)

self

@self is the currently running actor

Server

protocol

members

handle-call

(handle-call this from id message)

handle-cast

(handle-cast this from id message)

handle-info

(handle-info this message)

handle-timeout

(handle-timeout this)

init

(init this)

terminate

(terminate this cause)

set-state!

(set-state! x)
Sets the state of the currently running actor.
The state can be read with `@state`.

set-timeout!

(set-timeout! timeout unit)
Sets the timeout for the current gen-server

shutdown!

(shutdown! gs)(shutdown!)
Asks a gen-server or a supervisor to shut down

spawn

macro

(spawn :name? :mailbox-size? :overflow-policy? :trap? :lifecycle-handler? :scheduler? :stack-size? f & args)
Creates and starts a new actor running in its own, newly-spawned fiber.

f - the actor function, or an actor created with actor, gen-server etc..
args - (optional) arguments to for the function.

If `f` is an actor rather than an actor function, the optional parameters will be ignored.

Options:
* `:name` - The actor's name (that's also given to the fiber running the actor). The name can be a string
            or a keyword, in which case it's identical to the keyword's name (i.e. a name of `"foo"` is the same as `:foo`).
* `:mailbox-size` - The number of messages that can wait in the mailbox,
                    or -1 (the default) for an unbounded mailbox.
* `:overflow-policy` - What to do if a bounded mailbox overflows. Can be on of:
   - `:throw` - an exception will be thrown *into the receiving actor*
   - `:drop`  -  the message will be silently discarded
   - `:block` - the sender will block until there's room in the mailbox.
* `:trap` - If set to `true`, linked actors' death will send an exit message rather than throw an exception.
* `:lifecycle-handle` - A function that will be called to handle special messages sent to the actor.
                        If set to `nil` (the default), the default handler is used, which is what you
                        want in all circumstances, except for some actors that are meant to do some
                        special tricks.
* `:scheduler` - The `FiberScheduler` in which the fiber will run.
               If `:fj-pool` is not specified, then the pool used will be either the pool of the fiber calling
               `spawn-fiber`, or, if `spawn-fiber` is not called from within a fiber, a default pool.
* `:stack-size` - The initial fiber stack size.

state

@state is the state of the currently running actor.
The state can be set with `set-state!`

strand-factory

(strand-factory f)

supervisor

(supervisor name restart-strategy init)(supervisor restart-strategy init)
Creates (but doesn't start) a new supervisor

trap!

(trap!)
Sets the current actor to trap lifecycle events (like a dead linked actor)
and turn them into exit messages.
Same as adding `:trap true` to `spawn`.

unlink!

(unlink! actor2)(unlink! actor1 actor2)
Unlinks two actors. If only one actor is specified, unlinks the current actor from the
specified actor.

See: `link!`

unregister!

(unregister! x)(unregister!)
Unregisters an actor.

If no argument is supplied, unregisters the current actor.

unwatch!

(unwatch! actor2 monitor)
Makes an actor stop watching another actor

vref

(vref x)
Turns a value into an IDeref (makes it deref-able)

watch!

(watch! actor)
Makes the current actor watch another actor. Returns a watch object which is then
used in all relevant exit messages, and should also be used when calling `unwatch!`.

Unlike links, watches are assymetrical. If a the watched actor dies, the watching
actor (the actor calling this function), receives an exit message.

The message is a vector of 4 elements, of the following structure:

[:exit w actor cause]

`w` - the watch object returned from the call to `watch!`, which is responsible for the
      message being sent. If the `watch!` function is called more than once to watch
      the same actor, an exit message will be received several times, each one corresponding
      to an invocation of `watch!`, and each with a different value for `w`.
`actor` - the dead (watched) actor.
`cause` - the dead actor's cause of death: `nil` for a normal termination; a Throwable for
          an exceptional termination.

See: `unwatch!`, `link!`

whereis

(whereis actor-name)(whereis actor-name timeout unit)
Returns a registered actor by name, blocking until one is registered