Skull is a library for batching requests. Requests invoked in rapid succession are batched and performed as a single request batch.
bower install --save purescript-skull
Consider two requests that return numbers that you want to add. The requests are independent of each other; one does not depend on the result of the other. There are three approaches to performing these requests:
Perform the requests sequentially. That is, wait for the first request to complete before performing the second request. This is very straightforward:
do a <- request 1 b <- request 2 pure $ a + b
This approach suffers from the need to wait for the first request to finish before the second request begins, even though the requests are otherwise independent.
Perform the requests in parallel. The computation will take as long as the
longest request takes. This is also very straightforward, by using the
sequential $ (+) <$> parallel (request 1) <*> parallel (request 2)
However, the server will still receive two requests, and any overhead of sending a single request is being duplicated.
Combine the two requests into a single request, perform that, and split the response into two responses before returning. This approach does not suffer from either of the problems described above, but does require some more work. In particular, requests need to be combined, responses need to be split, and requests and responses must be matched up. Skull helps you with the latter, while leaving the former two up to you.
To use Skull, you must tell it how to combine requests and split responses. To
do this, you create a batcher. See the documentation of the
Batcher type to
see how to do this.
Next, you must create a state, which keeps track of pending requests. Given a
batcher, all you have to do is the following:
state <- newState batcher
You should use the same state value for all requests you want to batch together. Once you have a state value, you can start scheduling requests. The interface looks much like the parallel example above, but will in fact automatically use the provided batcher.
let action = (+) <$> requestA 1 <*> requestA 2 in runSkullA action state
runSkullA will return the sum of the two responses.
If your application is inherently concurrent, you may want to batch requests
that happen to be performed quickly after each other, but may not necessarily
always do so. This may happen if the requests come from different concurrent
parts of your application. You can use the non-applicative interface for this,
response <- request state 1