Clojure RPC, prototyping and early thoughts

Sun 27 November 2011
  • 手艺 tags:
  • clojure
  • opensource published: true comments: true

Last week, I prototyped an RPC framework, slacker, by clojure and for clojure.

What I did ?

Suppose you have a sets of clojure functions to expose. Define them under a namespace:
[cc lang="clojure"]
(ns slapi)
(defn timestamp []
(System/currentTimeMillis))

;; ...more functions
[/cc]

Expose the namespace with slacker server, on port 2104:
[cc lang="clojure"]
(use 'slacker.server)
(start-slacker-server (the-ns 'slapi) 2104)[/cc]

On the client side, we use the `defremote` macro to create a facade for `timestamp` function. This API will keep the client code consistent with local mode.
[cc lang="clojure"]
(use 'slacker.client)
(def sc (slackerc "localhost" 2104))
(defremote sc timestamp)
(timestamp)
[/cc]

Internally, slacker uses aleph for transport and carbonite for serialization. I forked carbonite and made it compatible with clojure 1.2 because the aleph mainline is still running on 1.2.

Going further

High-Order Functions

In clojure, functions are treated as first class value. Within memory, you can pass function as parameter to another function. However, this is not supported by serialization framework. So is it possible to add support for that in future?

Lazy sequence as parameter

This is another interesting feature in clojure function call. You can pass a lazy-sequence to clojure function. In RPC, it requires parameters to be evaluated on the server side.
[cc lang="clojure"]
(defn get-first [& args] (first args))
(apply get-first (range))
[/cc]
Example copied from StackOverflow

Coordinated states between several remote servers

With RPC, we can update states on several servers. So do we need something like distributed dosync:
[cc lang="clojure"]
(defremote a1 update-a1-state)
(defremote a2 update-a2-state)
(dosync-distributed
(update-a1-state some-value)
(update-a2-state some-value))
[/cc]
I'm not sure if this is a valid scenario in real world but I think it's an interesting topic.(distributed STM?)

Conclusion

RPC is the first step to distributed clojure world. I will keep you updated with my prototype.