Skip to main content

Posts

Showing posts from December, 2014

Asynchronous timeouts with CompletableFuture

One day I was rewriting poorly implemented multi-threaded code that was blocking at some point on Future.get():

public void serve() throws InterruptedException, ExecutionException, TimeoutException { final Future<Response> responseFuture = asyncCode(); final Response response = responseFuture.get(1, SECONDS); send(response); } private void send(Response response) { //... } This was actually an Akka application written in Java with a thread pool of 1000 threads (sic!) - all of them blocked on this get() call. Otherwise system couldn't keep up with the number of concurrent requests. After refactoring we got rid of all these threads and introduced just one, significantly reducing memory footprint. Let's simplify a bit and show examples in Java 8. The first step is to introduce CompletableFuture instead of plain Future (see: tip 9). It's simple if:

you control how tasks are submitted to ExecutorService: just use CompletableFuture.supplyAsync(..., executo…

Hazelcast member discovery using Curator and ZooKeeper

At one project I was setting up Hazelcast cluster in a private cloud. Within cluster all nodes must see each other, so during bootstrapping Hazelcast will try to locate other cluster members. There is no server and all nodes are made equal. There are couple techniques of discovering members implemented in Hazelcast; unfortunately it wasn't AWS so we couldn't use EC2 autodiscovery and multicast was blocked so built-in multicast support was useless. The last resort was TCP/IP cluster where addresses of all nodes need to be hard-coded in XML configuration:

<tcp-ip enabled="true"> <member>machine1</member> <member>machine2</member> <member>machine3:5799</member> <member>192.168.1.0-7</member> <member>192.168.1.21</member> </tcp-ip> This doesn't scale very well, also nodes in our cloud were assigned dynamically, thus it was not possible to figure out addresses prior runtime. H…

Accessing Meetup's streaming API with RxNetty

This article will touch upon multiple subjects: reactive programming, HTTP, parsing JSON and integrating with social API. All in one use case: we will load and process new meetup.com events in real time via non-bloking RxNetty library, combining the power of Netty framework and flexibility of RxJava library. Meetup provides publicly available streaming API that pushes every single Meetup registered all over the world in real-time. Just browse to stream.meetup.com/2/open_events and observe how chunks of JSON are slowly appearing on your screen. Every time someone creates new event, self-containing JSON is pushed from the server to your browser. This means such request never ends, instead we keep receiving partial data as long as we want. We already examined similar scenario in Turning Twitter4J into RxJava's Observable. Each new meetup event publishes a standalone JSON document, similar to this (lots of details omitted):

{ "id" : "219088449", "name" :…

Benchmarking impact of batching in Hystrix

In previous article "Batching (collapsing) requests in Hystrix" we looked at collapsing API in Hystrix. Check it out before proceeding with this article. Example presented there was rather artificial, merely presenting API. Today let's look at semi-real-life example and do some benchmarking. We already used random.org API some time ago as an example (see: Your first message - discovering Akka), let's use it again. Imagine our application calls the following API facade in order to fetch exactly one random number per request (generateIntegers(1)):

public interface RandomOrgClient { RandomIntegers generateIntegers(int howMany); } As you can see this method can easily fetch more than one number. You might wonder why it returns some fancy RandomIntegers class rather than, say List<Integer>? Well, a list of integers is just a data structure, it doesn't represent any business concept, while *random integers* leaves no room for speculation. Still unsurprisingly…