E
- @Beta public class Pipeline<E> extends Object
IMap.getAsync(Object)
or any other asynchronous call.
The main purpose of the pipeline is to control the number of concurrent requests
when using asynchronous invocations. This can be done by setting the depth using
the constructor. So you could set the depth to e.g 100 and do 1000 calls. That means
that at any given moment, there will only be 100 concurrent requests.
It depends on the situation what the optimal depth (number of invocations in
flight) should be. If it is too high, you can run into memory related problems.
If it is too low, it will provide little or no performance advantage at all. In
most cases a pipeline and a few hundred map/cache puts/gets should not lead to any
problems. For testing purposes we frequently have a pipeline of 1000 or more
concurrent requests to be able to saturate the system.
The Pipeline can't be used for transaction purposes. So you can't create a
Pipeline, add a set of asynchronous request and then not call results()
to prevent executing these requests. Invocations can be executed before the
results()
is called.
Pipelines can be used by both clients or members.
The Pipeline isn't threadsafe. So only a single thread should add requests to
the pipeline and wait for results.
Currently all ICompletableFuture
and their responses are stored in the
Pipeline. So be careful executing a huge number of request with a single pipeline
because it can lead to a huge memory bubble. In this cases it is better to
periodically, after waiting for completion, to replace the pipeline by a new one.
In the future we might provide this as an out of the box experience, but currently
we do not.
A pipeline provides its own backpressure on the system. So there will not be more
in flight invocations than the depth of the pipeline. This means that the pipeline
will work fine when backpressure on the client/member is disabled (default). Also
when it it enabled it will work fine, but keep in mind that the number of concurrent
invocations in the pipeline could be lower than the configured number of invocation
of the pipeline because the backpressure on the client/member is leading.
The Pipeline has been marked as Beta since we need to see how the API needs to
evolve. But there is no problem using it in production. We use similar techniques
to achieve high performance.Constructor and Description |
---|
Pipeline(int depth)
Creates a pipeline with the given depth.
|
Modifier and Type | Method and Description |
---|---|
ICompletableFuture<E> |
add(ICompletableFuture<E> future)
Adds a future to this Pipeline or blocks until there is capacity to add the future to the pipeline.
|
List<E> |
results()
Returns the results.
|
public Pipeline(int depth)
depth
- the maximum number of concurrent calls allowed in this pipeline.IllegalArgumentException
- if depth smaller than 1. But if you use depth 1, it means that
every call is sync and you will not benefit from pipelining at all.public List<E> results() throws Exception
The results are returned in the order the requests were done.
This call waits till all requests have completed.
Exception
- is something fails getting the results.public ICompletableFuture<E> add(ICompletableFuture<E> future) throws InterruptedException
This call blocks until there is space in the pipeline, but it doesn't mean that the invocation that returned the ICompletableFuture got blocked.
future
- the future to add.InterruptedException
- if the Thread got interrupted while adding the request to the pipeline.NullPointerException
- if future is null.Copyright © 2019 Hazelcast, Inc.. All Rights Reserved.