Mytec

Wednesday May 27, 2009

Grizzly 2.0: Streaming and Messaging

Originally, when designing Grizzly 2.0 Connection API, we were thinking that Streams could cover all the possible scenarios developers may have. and could be easily used with TCP and UDP transports. But when started to implement UDP transport, we came to conclusion, that it's not actually true. For sure UDP is message oriented protocol, but thought we assumed it will be easy to emulate that using Streams like:

streamWriter.writeInt(...);
streamWriter.writeLong(...);
streamWriter.flush();

for connected UDP Connection, or

streamWriter.writeInt(...);
streamWriter.writeLong(...);
streamWriter.flush(dstAddress); 

for non-connected UDP Connections. Similar trick could be done for reading UDP messages.

So, from API point of view, Streams could work fine even for message-oriented protocols, but the problem appears, when we build UDP server (have non-connected UDP socket). In this case server may receive packets from different clients, but as Streams are not thread-safe, we can process only one single client packet at the time and block other clients, until first packet will be completely processed. This fact creates sensitive performance issue for UDP server, because many UDP packets may get lost because of big delays in processing. For such a usecase we need possibility to not block the connection, when processing incoming message, but make the connection available to process next message. This is not doable with Streams, because of mentioned thread-safety limitation, so in Grizzly 2.0 M2 we've added message-based API for Connections.

Message-based API:

Message-based API is reachable via Connection interface, which is now extending Readable and Writable interfaces, and is represented by set of read and write methods:

  • Future<ReadResult<Buffer, L>> read(...);
  • Future<WriteResult<Buffer, L>> write(...);

where <L> represents source/destination address type (SocketAddress for NIO TCP and UDP transports).

Ok, with Connections it should be straightforward, how we can use Message-based API, what about FilterChains? In the original Grizzly samples, TransportFilter, which we add first to a FilterChain, provided us StreamReader/StreamWriter objects to be used by next Filters in chain. So TransportFilter was oriented to work just in Stream mode. Now it's possible to create TransportFilter, which will work in Message mode:

transport.getFilterChain().add(new TransportFilter(TransportFilter.Mode.Message)); 

if we add TransportFilter like above, then it will not provide Streams, which could be used by the rest of FilterChain, but message (Buffer), which could be accessed via FilterChainContext:

Buffer message = (Buffer) context.getMessage();

so next Filters in chain should deal directly with message, not Streams. 

Here is the simple example of using Message-based API for UDP echo server.

Stream-based API:

We discussed Stream-based API in one of my previous blogs. So here I just want to add, that for TCP transport we recommend to use Stream API, because it makes implementation easier for most of usecases and takes care about internal buffer management, optimizing memory allocation etc.

Let's try to make some summary for Streaming and Messaging API. For sure in each particular case, it's up to you to decide which API to use. Here are just our recommendations:

  • Streams API is recommended to be used with TCP transport and could be also used for connected UDP Connections;
  • Message API is recommended to be used with non-connected UDP Connections (UDP servers);

Tuesday May 26, 2009

Grizzly 2.0 M2 Release

Next Grizzly 2.0 milestone is reached.

Here is the list of new features available with Grizzly 2.0 M2:

  • UDP transport,
  • New Connection API, which lets Connections to operate in "message" mode. This API fits better to message oriented transports like UDP,
  • Performance improvements,
  • Codec API and specifically SSL and FilterChain Codecs,
  • Extended Transport API to support multi-binding, added support for unbind(),
  • Significantly improved documentation,
  • All-in-one OSGi bundle for framework, http and http-servlet available. You can launch them by just doing java -jar grizzly-<module>
In next blog I'll provide more details about Connection "stream" and "message" API and give simple example for UDP transport.

 

Calendar

Feeds

Search

Links

Navigation

Referrers