According to wikipedia, Staged Event-driven Architecture is an approach to software architecture that decomposes a complex, event-driven application into a set of stages connected by queues. We were using Java framework, stages, to implement queue based SEDA. As we are using more and more Clojure nowadays, I decide to re-implement it in Clojure language, and in Clojure way. It's papaline.
The most important difference between papaline and stages is the usage of IoC threads. Core.async introduces IoC threads for Clojure, which is a popular concurrent mechanism recently. In traditional queue based thread pool, threads are blocked on queue to wait for tasks. While for IoC threads, channels act similar to queues but no actual thread is blocked on channel. Once there is a task available in channel, an underlying thread will be picked to execute it. So for core.async, you don't have to assign a static thread pool to each channel. The channel will pick thread from a shared system thread pool on demand. In current core.async release, it's a fixed thread pool with (processors * 4) + 42 threads. That's much flexible and efficient.
Papaline takes advantages of this feature. The base concept in papaline is stage and pipeline. A pipeline is created with a ordered sequence of stages. Stages configured in a pipeline are connected with channels, instead of queues. Threads are automatically managed by core.async, and scheduled based on load of channels.
When you run a pipeline, the input data is sent to the inbound channel of the first stage. The stage will received the data and pick a thread to execute the function. Then the result is put into the second stage's inbound channel. The user-visible behavior is much like
comp, but in concurrent.
Also core.async offers different type of channel buffers: fixed
dropping-buffer. They are channels equivalent to j.u.c thread pool's
We have already deployed papaline in our asynchronous system and it works great by far. Find the project on github if you are interested in.