]
Sanne Grinovero commented on JGRP-2218:
---------------------------------------
Great Goal!
bq. Instead of copying, the application creates an instance of Buffer and ...
I'd suggest to immediately encapsulate in the strategy of obtaining such a {{Buffer}}
into some non-static service so that we can later introduce pooling and reuse.
The initial implementation could just create a new instance on each request and discard
them on close, but then it will be easier in the future to experiment with alternative
strategies and optimise some more details.
Call it {{BufferPool}} or {{BufferManagement}}, ... and every JGroups stack should start
one.
The methods like {{acquire}} and {{release}} could be package private and visible only to
the {{BufferPool}} ?
New buffers
-----------
Key: JGRP-2218
URL:
https://issues.jboss.org/browse/JGRP-2218
Project: JGroups
Issue Type: Feature Request
Reporter: Bela Ban
Assignee: Bela Ban
Fix For: 5.0
h3. Goal
Change payload in {{Message}} from byte[] arrays to a {{Buffer}} interface which can have
multiple implementations.
h3. Motivation
Currently, having to pass a byte[] array to a message leads to unnecessary copying:
* When an application has a ref to an NIO (direct) {{ByteBuffer}}, the bytes in the byte
buffer have to be copied into a byte[] array and then set in the message
* When the application sends around byte[] arrays, but also wants to add some additional
metadata, e.g. type (1000-byte requests/responses), it needs to create a new byte[] array
of (say) 1001 bytes and copy the data (1000 bytes) plus the request type (1 byte) into the
new copy. Example: {{MPerf}} and {{UPerf}}
h3. Design
Instead of copying, the application creates an instance of {{Buffer}} and sets the buffer
in {{Message}}. The {{Buffer}} is then passed all the way down into the transport where it
is marshalled and sent. There can be a number of buffer implementations, e.g.
* {{ArrayBuffer}}: wraps a byte[] array with an offset and length
* {{NioDirectBuffer}}: wraps an NIO direct {{ByteBuffer}}
* {{NioHeapBuffer}}: wraps an NIO heap-based {{ByteBuffer}}
* {{CompositeBuffer}}: wraps multiple Buffers. E.g. type (1 byte) and data (1000 bytes)
as described above
* {{IntBuffer}}: a single integer
* {{ObjectBuffer}}: has an Object and a ClassLoader (for reading), plus a Marshaller
which know how to marshal the object, this allows for objects to be passed in buffers and
they're only marshalled at the end (transport).
* {{PartialBuffer}}: a ref to a {{Buffer}}, with an offset and length
The {{Buffer}} interface has methods:
* {{size()}}
* {{writeTo(DataOutput)}}
* {{readFrom(DataInput)}}
* {{getInput()}}: this provides a {{DataInput}} stream for reading from the underlying
buffer
and possibly also
* {{acquire()}} and
* {{release()}} (for ref-counting).
Each buffer impl has an ID and it should be possible to register new impls. A
{{BufferFactory}} maintains a mapping between IDs and impl classes.
When marshalling a {{Buffer}}, the ID is written first, followed by the buffer's
{{writeTo()}} method. When reading buffers, the {{BufferFactory}} is used to create
instances from IDs.
h4. Fragmentation
When fragmenting a buffer, the fragments are instances of {{PartialBuffer}} which
maintains an offset and length over an underlying buffer. When marshalling a
{{PartialBuffer}}, only the part between offset and offset+length is written to the output
stream.
h4. Reference counting
If we implement ref-counting, then buffers can be reused as soon as the ref-count is 0.
For example, when sending a message, the buffer's ref-count could be incremented by
the app calling {{acquire()}}. (Assuming the message is a unicast message), {{UNICAST3}}
would increment the count to 2. This is needed because {{UNICAST3}} might have to
retransmit the message if it was lost on the network, and meanwhile the buffer cannot be
reused (changed). The app calls {{release()}} when the {{JChannel.send()}} call returns,
but the buffer cannot be reused until {{UNICAST3}} calls {{release()}} as well. This will
happen when an {{ACK}} for the given message has been received.