Skip to main content

Posts

RxJava vs Reactor

Summary:Stick to whichever library you already have on your CLASSPATH.If you get a choice, Reactor is preferable, RxJava 2.x is still a good alternativeIn case you’re on Android, then RxJava 2.x is your only choice Table of contents:APIType-safetyChecked exceptionsTestingDebuggingSpring supportAndroid developmentMaturitySummary Many people ask me, which library to use in their new projects (if any). Some are concerned that they learned RxJava 1.x and then 2.x came along, and the Reactor. Which one should they use? And some also wonder, what’s with this new java.util.concurrent.Flow? Let me clarify a few things. First of all, both versions of RxJava and Reactor are quite similar from a functional perspective. If you know 1.x or 2.x, Reactor will be very familiar, though you still have to learn about the differences. Secondly, Flow class (a set of interfaces, to be precise) is part of a reactive streams specification, bundled into JDK. This specification dictates that various reactive …

Brute-forcing a seemingly simple number puzzle

Something was bothering me for almost two decades. It was a pen and paper game that I learned when I was around 13. The rules are simple: on an empty 10x10 grid (100 squares in total) you put a number 1 on an arbitrary square. Starting from that square you can move horizontally or vertically jumping over two squares or diagonally jumping over one square. There you can place number 2. Your task is to reach number 100, filling all squares. You can not visit already visited squares. Here is an example of a solved game with a reduced 5x5 grid, starting at top-left corner:

12414225162158201310182311471536172212919 On the other hand, if the program makes bad choices, we might get stuck without reaching the perfect score of 25 (on a reduced 5x5 grid):

18291613517141047153619121811 Notice how we got stuck at number 19, unable to move anywhere and fill six remaining gaps. On an original 10x10 grid I never managed to reach the perfect score of 100. Countless hours wasted at school, of trial and …

Thread pool self-induced deadlocks

Summary (reading time: 10 minutes)Deadlocks are caused by many threads locking the same resourcesDeadlocks can also occur if thread pool is used inside a task running in that poolModern libraries like RxJava/Reactor are also susceptible A deadlock is a situation where two or more threads are waiting for resources acquired by each other. For example thread A waits for lock1 locked by thread B, whereas thread B waits for lock2, locked by thread A. In worst case scenario, the application freezes for an indefinite amount of time. Let me show you a concrete example. Imagine there is a Lumberjack class that holds references to two accessory locks:

import com.google.common.collect.ImmutableList; import lombok.RequiredArgsConstructor; import java.util.concurrent.locks.Lock; @RequiredArgsConstructor class Lumberjack { private final String name; private final Lock accessoryOne; private final Lock accessoryTwo; void cut(Runnable work) { try { accessoryOne.…

Sneak peek at spring-cloud-function serverless project

Almost a year ago Spring team announced spring-cloud-function umbrella project. It's basically a Spring's approach to serverless (I prefer the term function-as-a-service) programming. Function<T, R> becomes the smallest building block in a Spring application. Functions defined as Spring beans are automatically exposed e.g. via HTTP in RPC style. Just a quick example how it looks:

@SpringBootApplication public class FaasApplication { public static void main(String[] args) throws Exception { SpringApplication.run(FaasApplication.class, args); } @Bean Function<Long, Person> personById(PersonRepository repo) { return repo::findById; } } @Component interface PersonRepository { Person findById(long id); Mono<Person> findByIdAsync(long id); } The implementation of PersonRepository is irrelevant here. This is a valid Spring Boot application. But once you put spring-cloud-function dependency, beans of Function type come …

Reactive emoji tracker with WebClient and Reactor: aggregating data

In the first part we managed to connect to emojitracker.com and consume SSE stream that looks like this:

data:{"1F60D":1} data:{"1F3A8":1,"1F48B":1,"1F499":1,"1F602":1,"2764":1} data:{"1F607":1,"2764":2} Each message represents the number of various emojis that appeared on Twitter since the previous message. After a few transformations, we got a stream of hexadecimal Unicode values for each emoji. E.g. for {"1F607":1,"2764":2} we produce three events: "1F607", "2764", "2764". This is how we achieved it:

import org.springframework.http.codec.ServerSentEvent; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; final Flux<String> stream = WebClient .create("http://emojitrack-gostreamer.herokuapp.com") .get().uri("/subscribe/eps") …

Reactive emoji tracker with WebClient and Reactor: consuming SSE

In this article we will learn how to consume infinite SSE (server-sent events) stream with Spring's WebClient and Project Reactor. WebClient is a new HTTP client in Spring 5, entirely asynchronous and natively supporting Flux and Mono types. You can technically open thousands of concurrent HTTP connections with just a handful of threads. In standard RestTemplate one HTTP connection always needs at least one thread.

As an example, let's connect to this cute little site called emojitracker.com. It shows emojis being used in real-time on Twitter. Looks quite cool! All credits go to Matthew Rothenberg, the creator of that site. It's very dynamic so there obviously has to be some push mechanism underneath. I wore my hacker glasses and after hours of penetration testing, I discovered the following URL in Chrome DevTools: http://emojitrack-gostreamer.herokuapp.com/subscribe/eps. If you connect to it, you'll get a fast stream of emoji counters:

$ curl -v http://emojitrack-gostr…