Over a million developers have joined DZone.

gofor it

· Java Zone

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

The gofor macro

I've started working on a series of open source library code for Clojure called Dragonmark that roughly falls into three categories: utilities, a distributed CSP library, and a sample web app that demonstrates distributed CSP.

So, why?

Mostly, I think that the semantics for interprocess communication should be the same as the semantics for local communication. Clojure's core.async library provides a really nice set of APIs to communicate asynchronously, have backpressure, and in general "do the right thing."

But core.async does not provide any interprocess communication. In fact, nothing in Clojure-land does a good job of abstracting the transport layer and maintaining the semantics of core.async.

So, Dragonmark.

Making core.async less verbose

If you're going to do core.async right, there's a pattern... create a channel to receive a reply, send a message, wait for a timeout or an answer, close the channel, if the answer came from the channel, do something, else, do an error.

Using Scala and LAFuture is really easy in a for comprehension. I wanted something similar in Clojure-land, so I wrote the gofor macro.

Here's an example:

(gofor
  [a (foo channel {:thing value :other_thing other_value})]
  :let [b (+ a 1)]
  [c (baz other_channel)
   d (moose third_channel {:p b}
   :timeout 45000]
  (println a b c)
  :error (println &err &at))

The [a (foo channel {:thing value :other_thing other_value})] sends a message tochannel with {:_cmd "foo" :thing value :other_thing other_value :_return a_created_channel} and waits up to 30 seconds for an answer. If the answer doesn't arrive, the:error code is invoked and the comprehension is terminated. If the answer does come back, it's bound to a.

Next, we bind b to (a + 1).

Next, we kick off a parallel set of messages to other_channel and third_channel and wait up to 45 seconds for a response.

If we succeed, the (println a b c) code is executed.

It's a first pass at something that makes core.async more usable, especially in the case of cross-address space messaging where timeouts and failures should be expected and embraced.

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:

Published at DZone with permission of David Pollak. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}