Search This Blog

Posts

Today as an example we will take a very simple scenario: placing an order stores it and sends an e-mail about that order:

@Service
class OrderService @Autowired() (orderDao: OrderDao, mailNotifier: OrderMailNotifier) {
@Transactional
def placeOrder(order: Order) {
orderDao save order
mailNotifier sendMail order
}
}
So far so good, but e-mail functionality has nothing to do with placing an order. It's just a side-effect that distracts rather than part of business logic. Moreover sending an e-mail unnecessarily prolongs transaction and introduces latency. So we decided to decouple these two actions by using events. For simplicity I will take advantage of Spring built-in custom events but our discussion is equally relevant for JMS or other producer-consumer library/queue.

This article won't be about FitNesse. As matter of fact I don't like this tool very much and it seems to be loosing momentum, judging by the traffic on an official mailing list. Instead we will implement trivial internal DSL on top of Scala to simplify testing code, inspired by DoFixture. DoFixture in FitNesse allows one to write very readable acceptance tests almost in plain English using Wiki pages:

!|CarRegistrationFixtureTest|
!1 Registering car
!2 Registering brand new car for the first time
| register | brand new car | by | any owner | in | any country |
What might not be obvious is that the last line is actually executable and calls good old Java (or Scala for that matter) method:

Clojure, being designed for concurrency is a natural fit for our Back to the Future series. Moreover futures are supported out-of-the-box in Clojure. Last but not least, Clojure is the first language/library that draws a clear distinction between futures and promises. They are so similar that most platforms either support only futures or combine them. Clojure is very explicit here, which is good. Let's start from promises:

Promises
Promise is a thread-safe object that encapsulates immutable value. This value might not be available yet and can be delivered exactly once, from any thread, later. If other thread tries to dereference a promise before it's delivered, it'll block calling thread. If promise is already resolved (delivered), no blocking occurs at all. Promise can only be delivered once and can never change its value once set:

Series of articles about futures/promises without JavaScript would not be complete. Futures (more commonly named promises in JS land) are ubiquitous in JavaScript to the point where we almost don't recognize them any more. AJAX, timeouts and whole Node.JS are built on top of asynchronous callbacks. Nested callbacks (as we will see in just a second) are so hard to follow and maintain that the callback hell term was coined. In this article I will explain how promises can improve readability and modularize your code.

$.getJSON('square/3', function(square) {
console.info(square);
});
square/3 is an AJAX resource that yields 9 (3 square). I assume you are familiar with AJAX and understand that the callback logging 9 will be executed asynchronously once the response arrives from the server. As simple as that, but it quickly gets unwieldy once you start nesting, cha…

Akka is actor based, event-driven framework for building highly concurrent, reliable applications. Shouldn't come a surprise that concept of a future is ubiquitous in a system like that. You typically never block waiting for a response, instead you send a message and expect response to arrive some time in the future. Sounds like great fit for... futures. Moreover futures in Akka are special for two reasons: Scala syntax together with type inference greatly improve readability and monadic nature. To fully appreciate the latter advantage check out scala.Option Cheat Sheet if you haven't yet grasped monads in practice in Scala.

DeferredResult is a container for possibly not-yet-finished computation that will be available in future. Spring MVC uses it to represent asynchronous computation and take advantage of Servlet 3.0 AsyncContext asynchronous request handling. Just to give a quick impression how it works: