-
-
Notifications
You must be signed in to change notification settings - Fork 15
Services
To implement a service you have to first import it using either thrift-clj.core/import-services
or thrift-clj.core/import
with the :services
key. You might have to import the used types, too.
(require '[thrift-clj.core :as thrift])
(thrift/import-services org.example.PersonIndex)
;; or:
(thrift/import
(:services org.example.PersonIndex)
(:types org.example.Person))
Now, let's say the service looks like this:
service PersonIndex {
bool storePerson(1:i32 id, 2:Person p),
Person getPerson(1:i32 id)
}
You can now use service
, defservice
and defservice-fn
to create an instance of it.
Service takes the service class (or an alias) to implement, a number of options identified by a keyword, as well as a defrecord
/deftype
-like list of methods, and generates an instance of <Service>$Iface
.
Options include:
-
:let
: a vector of bindings; actually,service
does not benefit from this option since you could as well wrap it in alet
block completely - butdefservice
anddefservice-fn
probably do.
service
is a macro that directly returns a value, not creating any var. So, either use it directly with one of the server generation functions (see below), or store it somewhere.
(let [s (thrift/service PersonIndex
(storePerson [id {:keys[firstName lastName age]}]
(println "Storing" (str "[" lastName ", " firstName ", " age "]") "...")
(boolean (store-in-db id firstName lastName age)))
(getPerson [id]
(let [[f l a] (get-from-db id)]
(Person. f l a))))]
(thrift/serve-and-block!
(thrift/single-threaded-server s PORT)))
As you can see, thrift-clj handles Thrift objects for you, transparently converting them between their original and their Clojure representations. You can thus use things like destructuring, map lookup, etc...
These two macros are small helpers to declare service vars and service generation functions.
-
(thrift/defservice id ...)
translates to(def id (thrift/service ...))
, and -
(thrift/defservice-fn id [a b c] ...)
translates to(defn id [a b c] (thrift/service ...))
.
Just one less pair of parentheses.
There are three different server generation functions, each taking a service instance (generated by one of the macros above) as first parameter, followed by a port number and some options like :protocol
(see here for possible values), and producing an instance of org.apache.thrift.server.TServer
.
Options include:
-
:protocol
: the protocol to use for encoding/decoding; -
:bind
: the local address (a string) to bind the server to; -
:client-timeout
: maximum waiting time for responses/requests from a client.
You can create the following servers:
single-threaded-server
multi-threaded-server
-
nonblocking-server
( Note : This needs aframed
orfast-framed
client transport which is available since version "0.1.1".)
And these functions will start/stop them for you:
-
serve!
: returns a future containing the started server; -
serve-and-block!
: starts the server, blocks indefinitely; -
stop!
: shuts the server down.
Example using serve!
, stopping the server after 60s:
(thrift/defservice json-service ...)
(let [srv (thrift/multi-threaded-server json-service 1234
:bind "127.0.0.1"
:protocol :json)
f (thrift/serve! srv)]
(Thread/sleep 60000)
(thrift/stop! f)
@f)