The ClojureWerkz Blog

News and updates about ClojureWerkz projects

Spyglass 1.1.0-beta3 Is Released

TL;DR

Spyglass is a very fast Clojure client for Memcached (as well as Couchbase and Kestrel) built on top of SpyMemcached.

1.1.0-beta3 is a preview release that has breaking changes in clojurewerkz.spyglass.cache.

Changes between 1.1.0-beta2 and 1.1.0-beta3

Clojure 1.5 By Default

Spyglass now depends on org.clojure/clojure version 1.5.1. It is still compatible with Clojure 1.3+ and if your project.clj depends on a different version, it will be used, but 1.5 is the default now.

We encourage all users to upgrade to 1.5, it is a drop-in replacement for the majority of projects out there.

Asynchronous Cache Store

Spyglass now ships both sync and async implementations of clojure.core.cache.

To instantiate async store, use clojurewerkz.spyglass.cache/async-spyglass-cache-factory. clojurewerkz.spyglass.cache/spyglass-cache-factory was renamed to clojurewerkz.spyglass.cache/sync-spyglass-cache-factory.

Contributed by Joseph Wilk.

Fix Authentication Support

clojurewerkz.spyglass.client/text-connection and clojurewerkz.spyglass.client/bin-connection no longer fail when credentials are passed in.

Empty gets Responses

clojurewerkz.spyglass.client/gets now correctly handles responses for keys that do not exist.

GH issue: #4.

Change Log

We recommend all users to give 1.1.0-beta3 a try.

Spyglass change log is available on GitHub.

Spyglass is a ClojureWerkz Project

Spyglass is part of the group of libraries known as ClojureWerkz, together with

  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Elastisch, a minimalistic Clojure client for ElasticSearch
  • Monger, a Clojure MongoDB client for a more civilized age
  • Neocons, a feature rich idiomatic Clojure client for the Neo4J REST API * Welle, a Riak client with batteries included
  • Quartzite, a powerful scheduling library

and several others. If you like Spyglass, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

Michael on behalf of the ClojureWerkz Team

Clojure Documentation Progress Report: March 13th, 2013

Clojure Documentation Progress Report

The Clojure Documentation Site (a.k.a. CDS) publishes periodic reports to give the Clojure community a better idea of what clojure-doc.org has to offer.

New Content

New tuturials:

New guides:

Updates

Since our last update in November 2012, most of the guides got minor improvements. We won’t list them all here.

Thank You, Contributors

All these Clojure documentation improvements would not be possible without the help of the following people:

  • Alex P
  • Ambrose Bonnaire-Sergeant
  • Austin Chamberlin
  • Balint Erdi
  • Curtis Gagliardi
  • Daniel Szmulewicz
  • Dave Ray
  • Edward Tsech
  • Jeremy A
  • John Gabriele
  • Michael Klishin
  • Phil Hagelberg
  • Steven Proctor
  • Tom Cammann
  • Victor Neo
  • Vijay Kiran
  • _1126
  • gsnewmark

You Can Help!

How It Works

We have a repository on GitHub that has Markdown files with content and toolchain setup instructions. Just pick something that you are very familiar with or interested in and write.

When you are done, submit a pull request on GitHub and someone from the existing contributors team will suggest improvements or merge your work. It is that easy.

In order to make it easier for potential contributors to join the project, we will post a brief list of guides that do not require deep expertise and can benefit from contributions by complete beginners.

Improving Existing Guides

Guides that have structure and good chunk of the content in place but still have holes you can help us plug:

Writing New Content

If you want to start working on one of those articles or have existing content you’ve authored that can be ported, please let us know on the Clojure mailing list.

Excited about making Clojure documentation better? We need your help!

Fin

Michael Klishin on behalf of the Clojure Documentation Team.

Validateur 1.4.0 Is Released

TL;DR

Validateur is a functional validations library inspired by Ruby’s ActiveModel. Validateur 1.4 upgrades default Clojure dependency to 1.5.

Changes between Validateur 1.2.0 and 1.4.0

Clojure 1.5 By Default

Validateur now depends on org.clojure/clojure version 1.5.1. It is still compatible with Clojure 1.3+ and if your project.clj depends on a different version, it will be used, but 1.5 is the default now.

We encourage all users to upgrade to 1.5, it is a drop-in replacement for the majority of projects out there.

Change Log

We recommend all users to upgrade to 1.4.0.

Validateur change log is available on GitHub.

Validateur is a ClojureWerkz Project

Validateur is part of the group of libraries known as ClojureWerkz, together with

  • Monger, a Clojure MongoDB client for a more civilized age
  • Welle, a Riak client with batteries included
  • Elastisch, a minimalistic Clojure client for ElasticSearch
  • Neocons, a client for the Neo4J REST API
  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Quartzite, a powerful scheduling library

and several others. If you like Validateur, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

Michael on behalf of the ClojureWerkz Team

Pantomime 1.7.0 Is Released

TL;DR

Pantomime is a tiny Clojure library that deals with MIME types (Internet media types, “content types”). Pantomime 1.7 upgrades default Clojure dependency to 1.5.

Changes between Pantomime 1.5.0 and 1.7.0

Clojure 1.5 By Default

Pantomime now depends on org.clojure/clojure version 1.5.1. It is still compatible with Clojure 1.3+ and if your project.clj depends on a different version, it will be used, but 1.5 is the default now.

We encourage all users to upgrade to 1.5, it is a drop-in replacement for the majority of projects out there.

Change Log

We recommend all users to upgrade to 1.7.0.

Pantomime change log is available on GitHub.

Pantomime is a ClojureWerkz Project

Pantomime is part of the group of libraries known as ClojureWerkz, together with

  • Monger, a Clojure MongoDB client for a more civilized age
  • Welle, a Riak client with batteries included
  • Elastisch, a minimalistic Clojure client for ElasticSearch
  • Neocons, a client for the Neo4J REST API
  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Quartzite, a powerful scheduling library

and several others. If you like Pantomime, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

Michael on behalf of the ClojureWerkz Team

Langohr 1.0.0-beta13 Is Released

TL;DR

Langohr is a Clojure RabbitMQ client that embraces AMQP 0.9.1 Model.

1.0.0-beta13 is a development milestone release that has breaking API changes. While the previous API version will work for a while for backwards compatibility, we recommend all users to upgrade to the new one early.

Changes between Langohr 1.0.0-beta12 and 1.0.0-beta13

1.0.0-beta13 has BREAKING CHANGES:

langohr.consumers/subscribe Options Renamed

The options langohr.consumers/subscribe takes now have consistent naming:

  • :handle-consume-ok becomes :handle-consume-ok-fn
  • :handle-cancel becomes :handle-cancel-fn
  • :handle-cancel-ok becomes :handle-cancel-ok-fn
  • :handle-shutdown-signal-ok becomes :handle-shutdown-signal-ok-fn
  • :handle-recover-ok becomes :handle-recover-ok-fn
  • :handle-delivery-fn does not change

This makes handler argument names consistent across the board.

Previous options (:handle-cancel, etc) are still supported for backwards compatibility but will eventually be removed.

Change Log

Langohr change log is available on GitHub.

Langohr is a ClojureWerkz Project

Langohr is part of the group of libraries known as ClojureWerkz, together with

  • Elastisch, a minimalistic well documented Clojure client for ElasticSearch
  • Welle, a Riak client with batteries included
  • Monger, a Clojure MongoDB client for a more civilized age
  • Neocons, a client for the Neo4J REST API
  • Quartzite, a powerful scheduling library

and several others. If you like Langohr, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

Michael on behalf of the ClojureWerkz Team

Clojure 1.5 Compatibility of ClojureWerkz Projects

TL;DR

Clojure 1.5 is finally released. ClojureWerkz projects are compatible with it. It’s probably sunny outside, too.

Feel free to upgrade today!

Clojure 1.5 and ClojureWerkz

Clojure 1.5 is finally releases. While not a groundbreaking release, 1.5 brings more new features than 1.4 did. So, it’s natural to expect that many developers will consider upgrading to it soon.

One of the main goals of ClojureWerkz has always been making sure our libraries work with multiple Clojure versions (currently 1.3+). To hold to the promise, we run tests against multiple Clojure versions during development and on travis-ci.org. One of the versions is the master Clojure snapshot.

Starting with 1.5.0-RC* releases, we started testing several of our projects against it:

We are happy to report that none of those projects required any modifications to pass their test suites on Clojure 1.5.0.

Michael on behalf of the ClojureWerkz Team.

Langohr 1.0.0-beta12 Is Released

TL;DR

Langohr is a Clojure RabbitMQ client that embraces AMQP 0.9.1 Model.

1.0.0-beta12 is a development milestone release. We recommend all users to upgrade to it.

Changes between Langohr 1.0.0-beta11 and 1.0.0-beta12

Clojure-friendly Return Values

Previously functions such as langohr.queue/declare returned the underlying RabbitMQ Java client responses. In case a piece of information from the response was needed (e.g. to get the queue name that was generated by RabbitMQ), the only way to obtain it was via the Java interop.

This means developers had to learn about how the Java client works. Such responses are also needlessly unconvenient when inspecting them in the REPL.

Langohr 1.0.0-beta12 makes this much better by returning a data structure that behaves like a regular immutable Clojure map but also provides the same Java interoperability methods for backwards compatibility.

For example, langohr.queue/declare now returns a value that is a map but also provides the same .getQueue method you previously had to use.

Since the responses implement all the Clojure map interfaces, it is possible to use destructuring on them:

1
2
3
4
5
6
7
8
(require '[langohr.core  :as lhc])
(require '[langohr.queue :as lhq])

(let [conn    (lhc/connect)
      channel (lhc/create-channel conn)
      {:keys [queue] :as declare-ok} (lhq/declare channel "" :exclusive true)]
  (println "Response: " declare-ok)
  (println (format "Declared a queue named %s" queue)))

will output

1
2
Response:  {:queue amq.gen-G9bmz19UjHLBjyxhanOG3Q, :consumer-count 0, :message_count 0, :consumer_count 0, :message-count 0}
Declared a queue named amq.gen-G9bmz19UjHLBjyxhanOG3Q

langohr.confirm/add-listener Now Returns Channel

langohr.confirm/add-listener now returns the channel instead of the listener. This way it is more useful with the threading macro (->) that threads channels (a much more common use case).

langohr.exchange/unbind

langohr.exchage/unbind was missing in earlier releases and now added.

langohr.core/closed?

langohr.core/closed? is a new function that complements langohr.core/open?.

langohr.queue/declare-server-named

langohr.queue/declare-server-named is a new convenience function that declares a server-named queue and returns the name RabbitMQ generated:

1
2
3
4
5
6
7
(require '[langohr.core  :as lhc])
(require '[langohr.queue :as lhq])

(let [conn    (lhc/connect)
      channel (lhc/create-channel conn)
      queue   (lhq/declare-server-named channel)]
  (println (format "Declared a queue named %s" queue))

More Convenient TLS Support

Langohr will now correct the port to TLS/SSL if provided :port is 5672 (default non-TLS port) and :ssl is set to true.

Change Log

Langohr change log is available on GitHub.

Langohr is a ClojureWerkz Project

Langohr is part of the group of libraries known as ClojureWerkz, together with

  • Elastisch, a minimalistic well documented Clojure client for ElasticSearch
  • Welle, a Riak client with batteries included
  • Monger, a Clojure MongoDB client for a more civilized age
  • Neocons, a client for the Neo4J REST API
  • Quartzite, a powerful scheduling library

and several others. If you like Langohr, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

Michael on behalf of the ClojureWerkz Team

Elastisch 1.1.0-beta1 Is Released

TL;DR

Elastisch is a battle tested, small but feature rich and well documented Clojure client for ElasticSearch. It supports virtually every Elastic Search feature and has solid documentation.

1.1.0-beta1 is a development release that has several new features, most notably a native client with the same API as the REST one Elastisch already has.

Changes in 1.1.0-beta1

Native Client

Elastisch 1.1.0 includes a major new feature: native ElasticSearch client. The client uses ElasticSearch’s Java API, and can be used with both transport and node clients.

Rationale

Native client is more bandwidth efficient. It also can use SMILE (binary JSON format) to be more efficient on the wire.

Namespace Layout

Native client API in Elastisch is nearly identical to that of the REST API client and resides in clojurewerkz.elastisch.native and clojurewerkz.elastisch.native.* namespaces (similarly to how clojurewerkz.elastisch.rest clojurewerkz.elastisch.rest.* namespaces are organized).

Connections

Transport client (used for TCP/remote connections) connections are set up using clojurewerkz.elastisch.native/connect!. Note that you need to provide node configuration that at least has cluster name in it:

1
2
3
4
5
6
(require '[clojurewerkz.elastisch.native :as es])

;; note that transport client uses port 9300 by default.
;; it also can connect to multiple cluster nodes
(es/connect! [["127.0.0.1" 9300]]
             {"cluster.name" "elasticsearch_antares" })

Cluster name and transport node addresses can be retrieved via HTTP API, for example:

1
2
curl http://localhost:9200/_cluster/nodes
{"ok":true,"cluster_name":"elasticsearch_antares","nodes":...}}

Performing Operations

The Native client tries to be as close as possible to the existing REST client API. For example, document operation functions in clojurewerkz.elastisch.native.document, such as clojurewerkz.elastisch.native.document/create, follow clojurewerkz.elastisch.rest.document function signatures as closely as possible:

1
2
3
4
5
6
7
8
9
;; in the REPL
(require '[clojurewerkz.elastisch.native :as es])
(require '[clojurewerkz.elastisch.native.document :as doc])

(es/connect! [["127.0.0.1" 9300]]
             {"cluster.name" "elasticsearch_antares" })

(doc/put index-name index-type id document)
(doc/get index-name index-type id)

The same with returned results. Note, however, that ES transport client does have (very) minor differences with the REST API and it is not always possible for Elastisch to completely cover such differences.

Async Operations

Native client offers a choice of synchronous (blocking calling thread until a response is received) and asynchronous (returns a future) versions of multiple API operations:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
;; in the REPL
(require '[clojurewerkz.elastisch.native :as es])
(require '[clojurewerkz.elastisch.native.document :as doc])

(es/connect! [["127.0.0.1" 9300]]
             {"cluster.name" "elasticsearch_antares" })

(doc/put index-name index-type id document)

;; returns a response
(doc/get index-name index-type id)
;; returns a future that will eventually
;; contain a response
(doc/async-get index-name index-type id)

One notable exception to this is administrative operations (such as opening or closing an index). The rationale for this is that they are rarely executed on the hot code path (e.g. in tight loops), so convenience and better error visibility is more important for them.

GH issues: #17, #18, #20.

Note that native ElasticSearch client currently relies on ElasticSearch 0.90.0.Beta1 client libraries and some operations will only work with that version.

Bulk Request Support

Bulk requests are now supported. All the relevant code is in the clojurewerkz.elastisch.rest.bulk namespace. Here is a small example of bulk document indexing using this new API:

1
2
3
(require '[clojurewerkz.elastisch.rest.bulk :as eb])

(eb/bulk (eb/bulk-index doc1 doc2 doc3) :refresh true)

Contributed by Davie Moston.

Scroll Queries Support

Scroll queries are now easier to perform thanks to the new clojurewerkz.elastisch.rest.document/scroll function that takes a scroll id and amount of time retrieved documents and related information will be kept in memory for future retrieval. They are analogous to database cursors.

A short code example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(require '[clojurewerkz.elastisch.rest.document :as doc])
(require '[clojurewerkz.elastisch.query :as q])
(require '[clojurewerkz.elastisch.rest.response :refer [hits-from]])

(let [index-name   "articles"
      mapping-type "article"
      response     (doc/search index-name mapping-type
                               :query (q/query-string :query "*")
                               :search_type "scan"
                               :scroll "1m"
                               :size 1)
      scroll-id     (:_scroll_id response)
      scan-response (doc/scroll scroll-id :scroll "1m")
      scan-hits     (hits-from scan-response)]
  (println scan-hits))

Contributed by Davie Moston.

Cheshire Update

Cheshire dependency has been upgraded to version 5.0.2.

clj-http Update

clj-http dependency has been upgraded to version 0.6.4.

Count API No Longer Ignores Mapping Types

clojurewerkz.elastisch.rest.document/count no longer ignores mapping types.

GH issue: #6.

Count API now uses GET requests

clojurewerkz.elastisch.rest.document/count now correctly uses GET for requests without the query part andPOST for request that have it.

GH issue: #5.

Change Log

Elastisch change log is available on GitHub.

We recommend all users to give 1.1.0-beta1 a try.

Thank You, Contributors

Kudos to Davie Moston and Andrew Jones who contributed to this release.

Elastisch is a ClojureWerkz Project

Elastisch is part of the group of libraries known as ClojureWerkz, together with

  • Welle, a Riak client with batteries included
  • Monger, a Clojure MongoDB client for a more civilized age
  • Neocons, a client for the Neo4J REST API
  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Quartzite, a powerful scheduling library

and several others. If you like Elastisch, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

Michael on behalf of the ClojureWerkz Team

Titanium 1.0.0-alpha2 Is Released

TL;DR

Titanium is a powerful Clojure graph library that is built on top of Aurelius Titan. It combines a Clojure-friendly API and graph processing DSL with the power of Titan.

alpha2 is a development release that adds transaction control operations.

Changes between Titanium 1.0.0-alpha1 and 1.0.0-alpha2

Transaction Control Functions

clojurewerkz.titanium.graph/commit-tx! and clojurewerkz.titanium.graph/rollback-tx! commit and roll back current transaction, respectively. Note that closing a graph will automatically commit current transaction. Every operation that modifies the graph will automatically start a transaction if needed.

clojurewerkz.titanium.graph/get-vertices Now Accepts Keywords For Keys

clojurewerkz.titanium.graph/get-vertices now accepts keywords for keys, like many other functions in Titanium.

Change Log

Titanium change log is available on GitHub.

News and Updates

New releases and updates are announced on Twitter. Titanium also has a mailing list, feel free to ask questions and report issues there.

Titanium is a ClojureWerkz Project

Titanium is part of the group of libraries known as ClojureWerkz, together with

  • Welle, a Riak client with batteries included
  • Monger, a Clojure MongoDB client for a more civilized age
  • Elastisch, a minimalistic Clojure client for ElasticSearch
  • Neocons, a Clojure client for the Neo4J REST API
  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Quartzite, a powerful scheduling library

and several others. If you like Titanium, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

Michael on behalf of the ClojureWerkz Team.