• Stars
    star
    113
  • Rank 310,115 (Top 7 %)
  • Language
    Clojure
  • Created about 14 years ago
  • Updated about 13 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Actors library for Clojure

jobim

An actors library for Clojure modelled after Erlang OTP plaform.

External dependencies

Jobim has two dependencies:

  • Directory service: ZooKeeper
  • Messaging system: RabbitMQ/ZeroMQ

RabbitMQ or ZeroMQ both can be used as the underlying messaging solution. In order to use Jobim, ZeroMQ java bindings must be installed, including the native jni library.

Basic usage

starting a node : jobim/bootstrap-node

A path to a configuration file must be provided. The path must include the name of the node, the selected messaging mechanism and configuration options for RabbitMQ, ZeroMQ and ZooKeeper.

This is a sample configuration file:

;; RabbitMQ used
{:node-name "remote-test"
 :messaging-type :rabbitmq
 :messaging-options {:host "192.168.1.35"}
 :zookeeper-options ["192.168.1.35:2181" {:timeout 3000}]}

 This is a configuration file for ZeroMQ:

{:node-name "remote-test"
 :messaging-type :zeromq
 :messaging-options {:protocol-and-port "tcp://192.168.1.35:5555"}
 :zookeeper-options ["localhost:2181" {:timeout 3000}]}

Checking available nodes : jobim/nodes jobim/resolve-node-name

The nodes function returns a map with all the node names and their identifiers. The function resolve-node-name can be used to retrieve the indetifier of a node provided its name.

=> (use 'jobim)

nil

=> (bootstrap-node "node-config.clj")

"6811651bd83e4d428359b419e7f76a75"

=> (nodes)

{"osx" "5299491ea4184c02ad8c0fbc100c49f9", "linux" "6811651bd83e4d428359b419e7f76a75"}

Agent creation : jobim/spawn

We can define an actor using any Clojure function and the spawn function.

; A Sample echo actor
(defn ping
  ([]
     (loop [continue true
            msg (receive)]
       (cond-match
        [#"exit" msg]       (recur false msg)
        [#"exception" msg]  (throw (Exception.
                                     (str "Ping actor with PID:"
                                          (self)
                                          "received exception")))
        [[?from ?data] msg] (do (send! from data)
                            (recur true (receive)))))))

Creation of the actor:

=> (def *pid* (spawn examples/ping))

#'clojure.core/*pid*

=> *pid*

"5299491ea4184c02ad8c0fbc100c49f9.1"

Transforming a thread into an actor : jobim/spawn-in-repl

The REPL or any other thread can become an actor calling spawn-in-repl from the code being executed in the thread:

=> (spawn-in-repl)

"5299491ea4184c02ad8c0fbc100c49f9.2"

=> (send! *pid* [(self) 13123])

:ok

=> (receive)

13123

Sending and receiving : jobim/send! jobim/receive

This couple of function can be used to send and receive messages to and from actors. The PID of the actor must be provided. By default, any serializable java object can be send and retrieved.

=> (send! pid [(self) (java.util.Date.)]) :ok

=> (receive)

#<Date Fri Sep 03 13:20:26 CEST 2010>

RPC calls : jobim/rpc-call jobim/rpc-blocking-call

Used to execute a function call in a remote node. They can be used to spawn remote actors and retrieve the PID (using the blocking variant).

=> (nodes)

{"osx" "5299491ea4184c02ad8c0fbc100c49f9", "linux" "6811651bd83e4d428359b419e7f76a75"}

=> (resolve-node-name "linux")

"6811651bd83e4d428359b419e7f76a75"

=> (rpc-blocking-call (resolve-node-name "linux") "clojure.core/+" [1 2 3 4 5])

15

Spawning a remote actor:

=> (def *pid* (rpc-blocking-call (resolve-node-name "linux") "jobim/spawn" ["jobim.examples.actors/ping"]))

#'clojure.core/*pid*

=> *pid*

"6811651bd83e4d428359b419e7f76a75.1"

=> (send! *pid* [(self) 345])

nil

=> (receive)

345

Registering PIDs : jobim/register-name jobim/registered-names jobim/resolve-name

An actor can be registered with a globally available name using the register-name function. All registered names can be retrieved with the registered-names function.

To transform an actor name into a PID the resolve-name function can be used.

=> (def *ping* (spawn examples/ping))

#'clojure.core/*ping*

=> *ping*

"5299491ea4184c02ad8c0fbc100c49f9.8"

=> (register-name "ping" *ping*)

:ok

=> (registered-names)

{"ping" "5299491ea4184c02ad8c0fbc100c49f9.8"}

=> (resolve-name "ping")

"5299491ea4184c02ad8c0fbc100c49f9.8"

=> (send! (resolve-name "ping") [(self) 1234])

:ok

=> (receive)

1234

Error notifications : jobim/link

Two actors can be linked using the link function. From that moment onwards if one of the actors dies because of an exception or the node where it is being executed becomes unavailable due to a network partition, the other actor will receive a special message containing a signal.

=> (self)

"5299491ea4184c02ad8c0fbc100c49f9.1"

=> (def *pid* (spawn examples/ping))

#'clojure.core/*pid*

=> (link *pid*)

{"5299491ea4184c02ad8c0fbc100c49f9.1" ["5299491ea4184c02ad8c0fbc100c49f9.9"], "5299491ea4184c02ad8c0fbc100c49f9.9" ["5299491ea4184c02ad8c0fbc100c49f9.1"]}

=> ; the ping actor will throw an exception if receives a message containing the

"exception" string

=> (send! *pid* "exception")

:ok

=> (receive)

{:signal :link-broken, :from "5299491ea4184c02ad8c0fbc100c49f9.9", :cause "class java.lang.Exception:Ping actor received exception"}

Threadless actors : jobim/spawn-evented jobim/react-loop jobim/react

To avoid the limitation on the number of java threads that can be created in a single java VM, an evented actor can be created not attached to a single thread.

Functions react-loop and react can be used as subtitues of loop and receive in the code of the evented actor.

The evented actor must be started with the spawn-evented function.

This is an example of the evented actor equivalent to the previously shown echo actor.

(defn ping-evented
  ([]
     (let [name "test evented"]
       (react-loop [c 0]
         (react [msg]
           (cond-match
             [#"exit" msg]       false
             [#"exception" msg]  (throw (Exception. "Ping actor received exception"))
             [[?from ?data] msg] (do
                                   (send! from (str "actor " name " says "data " " c))
                                   (recur (inc c))))))))))

Tests

To run the tests follow the next instructions:

  • edit the test-node.clj file inserting the right configuration.

  • edit test/jobim/test/jobim.clj and select the right communication mechanism:

    (defonce messaging-to-test :rabbitmq)

  • Start the relevant services: ZooKeeper and RabbitMQ/ZeroMQ

  • Start the test node that will execute the test-node.clj configuration:

$ java -cp jobim-0.0.4-SNAPSHOT-standalone.jar -Djava.library.path=/usr/local/lib jobim.main test-node.clj

** Jobim node started **

- node-name: remote-test

- messaging-type :rabbitmq

- messaging-args {:host "192.168.1.35"}

- zookeeper-args ["192.168.1.35:2181" {:timeout 3000}

clojure.core=>

  • Run the tests using

$ lein test

License

Copyright (C) 2010 Antonio Garrote

Distributed under the LGPL

More Repositories

1

rdfstore-js

JS RDF store with SPARQL support
JavaScript
561
star
2

clj-ml

A machine learning library for Clojure built on top of Weka and friends
Clojure
148
star
3

palermo

Palermo a job processing system inspired by resque for the JVM and RabbitMQ
JavaScript
69
star
4

json-ld-macros

Declarative transformation of JSON APIs into JSON-LD
JavaScript
68
star
5

clj-tesseract

Clojure wrapper for the Tesseract OCR software
C++
55
star
6

clj-plaza

clojure's rdf framework
JavaScript
49
star
7

apricot-soup

HTML manipulation library for Clojure
Clojure
39
star
8

lein-javac

a javac plugin for the leiningen clojure's building system
Clojure
36
star
9

semantic-ko

declarative web interfaces using semantic data
JavaScript
32
star
10

typed.rb

Gradual type checker for Ruby
Ruby
30
star
11

egearmand-server

erlang implementation of gearman server
Erlang
28
star
12

clj-haml

a haml like template HTML library for clojure
Clojure
27
star
13

levanzo

Building hypermedia APIs in Clojure using Hydra and Triple Fragment Patterns
Clojure
26
star
14

clj-r2rml

Clojure implementation of the W3C proposal R2RML: RDB to RDF mapping language
Objective-J
25
star
15

clj-control

control abstractions for the Clojure programming language
Clojure
19
star
16

NodeJS-WebID-demo

JavaScript
14
star
17

clj-s4

Clojure library for the Yahoo S4 distributed streams framework
Clojure
13
star
18

mahout-vis

Visualization utils for Mahout and the Clojure REPL
Clojure
12
star
19

hiccup-rdfa

RDFa function for hiccup templates that can be used in a Clojure Ring app
Clojure
12
star
20

rdf-raptor-node-js

Node.js extension for the Raptor RDF library
C++
11
star
21

clojure_kilim

Clojure/Kilim integration
Java
11
star
22

stardog-rb

Ruby bindings for Stardog HTTP API
Ruby
10
star
23

erlfaye

comet ++ websockets ++ erlang
Erlang
10
star
24

tokengame

modelling distributed systems in Clojure
Clojure
9
star
25

mondello

Mondello is a free graphical client for Docker, Docker Machine, Docker Compose for OSX
JavaScript
9
star
26

clojure-grizzly-trial

a sample clojure-grizzly adapter based on jruby-grizzly
Clojure
8
star
27

cronparser.erl

Crontab parsing and date computation functionality for erlang
Erlang
8
star
28

Chinarro

Chinarro is a version of Pocho who likes parenthesis
Clojure
7
star
29

micrograph.js

graph data layer for JS client apps
JavaScript
7
star
30

sparql-clj-v8-integration

an experiment embedding V8 into Clojure
JavaScript
6
star
31

semantic_rest

toolkit for the creation of semantic restful web services
JavaScript
5
star
32

serenade.js

JS music library based on "Music for Geeks and Nerds"
JavaScript
5
star
33

conf_rails_hispana_2009

a sample project for the rails conf hispana 2009
Ruby
5
star
34

clj-tuples

Support for tuples and pattern matching in clojure
Clojure
4
star
35

clj-plaza-rabbit

Yet another RabbitMQ Clojure wrapper
Clojure
4
star
36

geektalk

a demo JS app using RDF to link data from different APIs
JavaScript
4
star
37

exceptions_begone_dispatcher

Pushing live exceptions (begone!) from one application to your websockets enabled browser
Erlang
3
star
38

CortesAbiertas---Abredatos-2010

JavaScript
3
star
39

cassandra-wrapper

a Clojure 1.2 wrapper for Cassandra Thrift API aiming current version of Cassandra
3
star
40

social.rdf

Javascript platform to aggregate and publish social data associated to a WebID
JavaScript
3
star
41

linkedvis

Grammar of Graphics style Visualization Toolkit for RDF
JavaScript
3
star
42

Plaza

Non object oriented, non SQL based, non MVC centered web framework for building web applications consisting of sets of semantic RESTful web services.
Erlang
3
star
43

grel

Query and manipulation library of ruby objects in a graph
Ruby
2
star
44

pivotal_tracker_iphone

an iphone client for pivotal tracker (http://www.pivotaltracker.com)
2
star
45

clj-raml

RAML library in Clojure
Clojure
2
star
46

clj-LOGO

a clojure interpreter for the LOGO programming language that runs on Google App Engine
Clojure
2
star
47

coding-test

the coding test
1
star
48

dbwidgets

widgets+dashboard demo app using DBPedia info
JavaScript
1
star