WebSocket client API
Peter Levart
peter.levart at gmail.com
Thu Oct 15 15:24:26 UTC 2015
Hi Pavel,
There's a RFR being discussed on core-libs-dev: "8138696 :
java.lang.ref.Cleaner - an easy to use alternative to finalization".
Although it does not currently support it, I have been doing experiments
with FinalReference(s) (a package-private subtype of Reference that is
used internally to support finalization) that allowed me to code a
simple pool of recyclable objects that works with the help of GC and
reachability.
The idea is very simple:
ConcurrentLinkedDequeue<T> pool = ...;
Cleaner cleaner = ...;
T getPooledInstance(Supplier<T> factory) {
T instance = pool.pollLast();
if (instance == null) {
instance = factory.get();
}
// register cleanup to recycle the instance
cleaner.finalizableCleanup(instance, pool::addFirst);
}
.... finalize() method allows for cleanup to be performed at most once
for each finalizable instance, but an API like Cleaner that explicitly
registers a FinalReference with an instance would allow it to be
recycled and re-registered multiple times.
If you are interested to explore this possibility for recycling of
ByteBuffer(s), I can try proposing this to the Cleaner API.
Regards, Peter
On 10/13/2015 11:40 AM, Pavel Rappo wrote:
> Hi Simone,
>
>> On 8 Oct 2015, at 20:51, Simone Bordet <simone.bordet at gmail.com> wrote:
>>
>> The *API* should provide a callback to notify when the ByteBuffer has
>> been consumed.
> Here is a proposed mechanism for managing buffers used by Listener.
>
> 1. WebSocket.Builder gets 2 new methods (may not be an actual javadoc):
>
> /**
> * Specifies a function that provides {@code ByteBuffer}s for {@code
> * WebSocket} to receive Binary, Ping and Pong messages' payload to.
> *
> * <p> The function is called by {@code WebSocket} with a number of
> * bytes should remain in the required buffer. This serves as a hint
> * from the implementation to a user.
> *
> * @param provider the providing function
> * @return this builder
> */
> public Builder byteBuffersForListener(IntFunction<? extends ByteBuffer> provider);
>
> /**
> * Specifies a function that provides {@code CharBuffer}s for {@code
> * WebSocket} to receive Text and Close messages' payload to.
> *
> * <p> The function is called by {@code WebSocket} with a number of
> * chars should remain in the required buffer. This serves as a hint
> * from the implementation to a user.
> *
> * @param provider the providing function
> * @return this builder
> */
> public Builder charBuffersForListener(IntFunction<? extends CharBuffer> provider);
>
> 2. If a user wants to use their own strategy of allocation/reuse they are fully
> in charge of this. For example:
>
> IntFunction<? extends CharBuffer> provider = (r) -> {
> CharBuffer charBuffer = pool.getWithRemaining(r);
> if (charBuffer == null)
> charBuffer = CharBuffer.allocate(r);
> return charBuffer;
> };
>
> ...
> builder.charBuffersForListener(provider) ... .buildAsync();
> ...
>
> Later in the listener far, far away:
>
> @Override
> public void onText(CharBuffer payload, boolean isLast) {
> // ...
> ws.sendText(payload, isLast).thenRun(() -> pool.recycle(payload));
> }
>
> Since the user constructs both the listener and the provider, they surely may now
> of each other, so the 'pool' can be easily captured by the listener.
>
> 3. On the other hand we could specify a set of predefined providers, and default
> behaviour like:
>
> * one off provider: constructs buffers on demand for one time use
> * reusing provider: always returns a buffer to the implementation at the
> end of the onXXX invocation
>
> In both cases above the user doesn't have to know about some additional
> recycle-handlers. Hence there's no need for onXXX methods to change their
> signatures to accommodate for it.
>
> What would you think about it?
>
> -Pavel
>
More information about the net-dev
mailing list