176 Commits

Author SHA1 Message Date
Trustin Lee
132af3a485 Introduce ChannelHandlerInvoker, dedeciated for invoking event handler methods, and move most handler invocation code in ChannelHandlerContext to the default ChannelHandlerInvoker implementation
- Fixes #1912
- Add ChannelHandlerInvoker and its default implementation
- Add pipeline manipulation methods that accept ChannelHandlerInvoker
- Rename Channel(Inbound|Outbound)Invoker to
  Channel(Inbound|Outbound)Ops to avoid confusion
- Remove the Javadoc references to the package-private interfaces
2013-11-21 14:14:23 +09:00
Trustin Lee
26415b8f4c Use StringUtil.simpleClassName(..) instead of Class.getSimpleName() where necessary
- Class.getSimpleName() doesn't render anonymous classes very well
- + some minor cleanup
2013-11-04 19:42:33 +09:00
bgallagher
c149f4bcc0 Remove support from deregister a Channel from a EventLoop manually 2013-08-29 18:11:16 +02:00
Norman Maurer
48a7a21541 Correctly update Channel.isWritable() when the write happens from outside the EventLoop in a fast fashion. Fixes [#1697]
Introduce a new interface called MessageSizeEstimator. This can be specific per Channel (via ChannelConfig). The MessageSizeEstimator will be used to estimate for a message that should be written. The default implementation handles ByteBuf, ByteBufHolder and FileRegion. A user is free to plug-in his/her own implementation for different behaviour.
2013-08-07 10:10:43 +02:00
Trustin Lee
17b91f416d Remove an irrelevant comment
.. because firedChannelActive is gone long ago
2013-08-05 16:50:25 +09:00
Norman Maurer
a06295fe0a Correctly fix problem in ByteToMessageDecoder and ReplayingDecoder which could let to have a released buffer passed to the decode methods.
This fixes #1664 and revert also the original commit which was meant to fix it 3b1881b523e61496d9bc50e44927f7b58fa449e6 . The problem with the original commit was that it could delay handlerRemove(..) calls and so mess up the order or forward bytes to late.
2013-08-01 09:54:07 +02:00
Trustin Lee
81de2275e4 Remove unnecessary traversal of pipeline which occurs when a Channel is closed
- Remove unnecessary ascending traversal of pipeline in DefaultChannelHandlerContext.freeInbound()
- Move DefaultChannelHandlerContext.teardownAll() to DefaultChannelPipeline
2013-07-31 20:45:37 +09:00
Trustin Lee
3b1881b523 Make sure ChannelHandler.handlerRemoved() is invoked while handler methods are not running
- Fixes #1664
2013-07-31 20:35:51 +09:00
Norman Maurer
2871079c4a [#1557] Make the contract of Channel.Unsafe.flush() more clear
* Remove boolean parameter from Channel.Unsafe.flush() method
* Move NIO related things to AbstractNioChannel.NioUnsafe
2013-07-12 19:45:31 +02:00
Trustin Lee
99716993f6 Add a boolean parameter to Channel.Unsafe.flush() so that SelectionKey state check can be bypassed. 2013-07-12 20:14:50 +09:00
Jeff Pinner
224f05e626 Use correct permission mode for java files 2013-07-10 21:58:12 +02:00
Norman Maurer
b57d9f307f Allow per-write promises and disallow promises on flush()
- write() now accepts a ChannelPromise and returns ChannelFuture as most
  users expected.  It makes the user's life much easier because it is
  now much easier to get notified when a specific message has been
  written.
- flush() does not create a ChannelPromise nor returns ChannelFuture.
  It is now similar to what read() looks like.
2013-07-11 00:49:48 +09:00
Trustin Lee
26e9d70457 Remove channelReadSuspended / Rename messageReceived(Last) to channelRead(Complete)
- Remove channelReadSuspended because it's actually same with messageReceivedLast
- Rename messageReceived to channelRead
- Rename messageReceivedLast to channelReadComplete

We renamed messageReceivedLast to channelReadComplete because it
reflects what it really is for.  Also, we renamed messageReceived to
channelRead for consistency in method names.
2013-07-09 23:58:51 +09:00
Trustin Lee
cbd8817905 Remove MessageList from public API and change ChannelInbound/OutboundHandler accordingly
I must admit MesageList was pain in the ass.  Instead of forcing a
handler always loop over the list of messages, this commit splits
messageReceived(ctx, list) into two event handlers:

- messageReceived(ctx, msg)
- mmessageReceivedLast(ctx)

When Netty reads one or more messages, messageReceived(ctx, msg) event
is triggered for each message.  Once the current read operation is
finished, messageReceivedLast() is triggered to tell the handler that
the last messageReceived() was the last message in the current batch.

Similarly, for outbound, write(ctx, list) has been split into two:

- write(ctx, msg)
- flush(ctx, promise)

Instead of writing a list of message with a promise, a user is now
supposed to call write(msg) multiple times and then call flush() to
actually flush the buffered messages.

Please note that write() doesn't have a promise with it.  You must call
flush() to get notified on completion. (or you can use writeAndFlush())

Other changes:

- Because MessageList is completely hidden, codec framework uses
  List<Object> instead of MessageList as an output parameter.
2013-07-09 23:51:48 +09:00
Trustin Lee
734ec51ac9 Allow specifying 0 as the default number of threads when instantiating an EventLoopGroup
- Fixes #1426
- We already allow a user instantiate an EventLoopGroup with the default number of threads via the default constructor, so I think it's OK although it's not always optimal.
2013-06-27 10:39:39 +09:00
Trustin Lee
25c51279cf Revert "[#1442] Make sure closing the channel will not cause an UnsupportedOperationException"
This reverts commit a1a86b9de48e4696e3496904dd972336f57b4a0b because the
semantic of ctx.isRemoved() is confusing to a user - why is
ctx.isRemoved() false when handlerRemoved() is invoked? A better
solution would be check if the connection is inactive and mark the
promise as failure before attempting to write anything.
2013-06-14 10:47:31 +09:00
Norman Maurer
a1a86b9de4 [#1442] Make sure closing the channel will not cause an UnsupportedOperationException 2013-06-13 18:10:56 +02:00
Trustin Lee
f178b8d421 Suppress duplicate warning message printed when a message reaches at the end of pipeline 2013-06-13 13:23:52 +09:00
Norman Maurer
3be25694d0 Add ChannelHandlerContext.isRemoved() to easily detect the removal of a ChannelHandler while in a method. 2013-06-10 11:16:05 +02:00
Trustin Lee
14158070bf Revamp the core API to reduce memory footprint and consumption
The API changes made so far turned out to increase the memory footprint
and consumption while our intention was actually decreasing them.

Memory consumption issue:

When there are many connections which does not exchange data frequently,
the old Netty 4 API spent a lot more memory than 3 because it always
allocates per-handler buffer for each connection unless otherwise
explicitly stated by a user.  In a usual real world load, a client
doesn't always send requests without pausing, so the idea of having a
buffer whose life cycle if bound to the life cycle of a connection
didn't work as expected.

Memory footprint issue:

The old Netty 4 API decreased overall memory footprint by a great deal
in many cases.  It was mainly because the old Netty 4 API did not
allocate a new buffer and event object for each read.  Instead, it
created a new buffer for each handler in a pipeline.  This works pretty
well as long as the number of handlers in a pipeline is only a few.
However, for a highly modular application with many handlers which
handles connections which lasts for relatively short period, it actually
makes the memory footprint issue much worse.

Changes:

All in all, this is about retaining all the good changes we made in 4 so
far such as better thread model and going back to the way how we dealt
with message events in 3.

To fix the memory consumption/footprint issue mentioned above, we made a
hard decision to break the backward compatibility again with the
following changes:

- Remove MessageBuf
- Merge Buf into ByteBuf
- Merge ChannelInboundByte/MessageHandler and ChannelStateHandler into ChannelInboundHandler
  - Similar changes were made to the adapter classes
- Merge ChannelOutboundByte/MessageHandler and ChannelOperationHandler into ChannelOutboundHandler
  - Similar changes were made to the adapter classes
- Introduce MessageList which is similar to `MessageEvent` in Netty 3
- Replace inboundBufferUpdated(ctx) with messageReceived(ctx, MessageList)
- Replace flush(ctx, promise) with write(ctx, MessageList, promise)
- Remove ByteToByteEncoder/Decoder/Codec
  - Replaced by MessageToByteEncoder<ByteBuf>, ByteToMessageDecoder<ByteBuf>, and ByteMessageCodec<ByteBuf>
- Merge EmbeddedByteChannel and EmbeddedMessageChannel into EmbeddedChannel
- Add SimpleChannelInboundHandler which is sometimes more useful than
  ChannelInboundHandlerAdapter
- Bring back Channel.isWritable() from Netty 3
- Add ChannelInboundHandler.channelWritabilityChanges() event
- Add RecvByteBufAllocator configuration property
  - Similar to ReceiveBufferSizePredictor in Netty 3
  - Some existing configuration properties such as
    DatagramChannelConfig.receivePacketSize is gone now.
- Remove suspend/resumeIntermediaryDeallocation() in ByteBuf

This change would have been impossible without @normanmaurer's help. He
fixed, ported, and improved many parts of the changes.
2013-06-10 16:10:39 +09:00
Norman Maurer
89f1f3f4d1 [#1399] DefaultChannelHandlerPipeline.firstContext() should return null if no user handlers are in in the pipeline 2013-05-27 15:45:34 +02:00
Trustin Lee
2040b07849 Free the cleared buffer as early as possible / Better naming 2013-05-16 19:41:02 +09:00
Trustin Lee
dc13b68632 Make sure ChannelHandler.handlerRemoved() is always invoked
- Fixes #1366: No elegant way to free non-in/outbound buffers held by a handler
- handlerRemoved() is now also invoked when a channel is deregistered, as well as when a handler is removed from a pipeline.
- A little bit of clean-up for readability
- Fix a bug in forwardBufferContentAndRemove() where the handler buffers are not freed (mainly because we were relying on channel.isRegistered() to determine if the handler has been removed from inside the handler.
- ChunkedWriteHandler.handlerRemoved() is unnecessary anymore because ChannelPipeline now always forwards the content of the buffer.
2013-05-16 19:32:39 +09:00
Trustin Lee
670d3f53a8 Make uninitialization code in DefaultChannel easier to understand
.. by fixing bad / outdated method names
2013-05-16 16:18:01 +09:00
Trustin Lee
1e0c83db23 Introduce AddressedEnvelope message type for generic representation of an addressed message
- Fixes #1282 (not perfectly, but to the extent it's possible with the current API)
- Add AddressedEnvelope and DefaultAddressedEnvelope
- Make DatagramPacket extend DefaultAddressedEnvelope<ByteBuf, InetSocketAddress>
- Rename ByteBufHolder.data() to content() so that a message can implement both AddressedEnvelope and ByteBufHolder (DatagramPacket does) without introducing two getter methods for the content
- Datagram channel implementations now understand ByteBuf and ByteBufHolder as a message with unspecified remote address.
2013-05-01 17:04:43 +09:00
Norman Maurer
61327b5871 Simplify a bit 2013-04-30 07:17:07 +02:00
Trustin Lee
7884574c7b Remove freeInboundBuffer() and freeOutboundBuffer() which has no value
- Fixes #1308

freeInboundBuffer() and freeOutboundBuffer() were introduced in the early days of the new API when we did not have reference counting mechanism in the buffer. A user did not want Netty to free the handler buffers had to override these methods.

However, now that we have reference counting mechanism built into the buffer, a user who wants to retain the buffers beyond handler's life cycle can simply return the buffer whose reference count is greater than 1 in newInbound/OutboundBuffer().
2013-04-25 09:15:55 +09:00
Trustin Lee
1b3d7f5325 Make sure handlerAdded() is called before forwarding the buffer content of the removed handler
- Added a test case that reproduces the problem in ReplayingDecoderTest
- Call newHandler.handlerAdded() *before* oldHandler.handlerRemoved() to ensure newHandlerAdded() is called before forwarding the buffer content of the old handler in replace0().
2013-04-24 19:25:43 +09:00
Trustin Lee
99b999760a Move multiplicity check to the early stage
.. no need to do it late
2013-04-24 19:02:34 +09:00
Trustin Lee
6282b31bc0 Format 2013-04-24 18:57:14 +09:00
Trustin Lee
7c5dc363fb Rename methods to catch up the recent changes in handler life cycle listener methods / Ensure to call handlerRemoved() even if ctx.forwardContentAndRemove() failed 2013-04-24 18:55:51 +09:00
Trustin Lee
c72b5341a3 ChannelHandler.handlerRemoved() must be invoked *after* the handler has been removed completely and its buffers should be inaccessible. 2013-04-24 18:46:35 +09:00
Trustin Lee
5d5c60bdd3 Fix a bug where fireInboundBufferUpdated() and flush() swallow the event too early
- Fixes #1292
- Replace DefaultChannelPipeline.inbound/outboundShutdown flag with per-context flags
- Update the flags in free() / freeInbound() / freeOutbound() for clarity
2013-04-23 13:35:32 +09:00
Trustin Lee
e80fb65c36 Clean up the pipeline implementation / Ensure Embedded*Channel does not run pending tasks immediately
- Replace ugly 'prev != null' check with explicit event scheduling
- Fix an incorrect flag operation in freeHandlerBuffersAfterRemoval()
- Fix a bug in AbstractEmbeddedChannel.doRegister where it makes pending tasks immediately, where the pending tasks actually triggers inbound events
- Remove unnecessary suppression of inboundBufferUpdated() event in DefaultChannelPipeline, which potentially hides an event ordering bug. Unfortunately, I don't remember why I added it in cca35454d214611792067c89b78f7477aae3a323.
2013-04-22 19:41:00 +09:00
Trustin Lee
c01d37ad05 Merge forwardBufferContent and setRemoved() 2013-04-22 14:47:17 +09:00
Norman Maurer
ca5554dfe7 [#1236] Fix problem where adding a new ChannelHandler could block the eventloop
This change also introduce a few other changes which was needed:
 * ChannelHandler.beforeAdd(...) and ChannelHandler.beforeRemove(...) were removed
 * ChannelHandler.afterAdd(...) -> handlerAdded(...)
 * ChannelHandler.afterRemoved(...) -> handlerRemoved(...)
 * SslHandler.handshake() -> SslHandler.hanshakeFuture() as the handshake is triggered automatically after
   the Channel becomes active
2013-04-19 07:00:50 +02:00
Norman Maurer
d8387fa4c3 [#858] Merge ChannelPipeline.replaceAndForward into replace and removeAndForward into remove 2013-04-13 18:19:33 +02:00
Andrew Cox
3f8a830963 Fix DefaultChannelPipeline.first() so that it returns null when only the sentinel handlers remain (this is how DefaultChannelPipeline.last() works already) 2013-04-03 06:55:55 +02:00
Trustin Lee
9b208028ef Use clearer term when data is discarded by pipeline 2013-03-21 20:22:25 +09:00
Trustin Lee
9c96791176 Move the methods that's only used by DefaultChannelPipeline to DefaultChannelPipeline 2013-03-14 15:01:35 +09:00
Trustin Lee
d55567e21b Remove DefaultChannelHandlerContext.needsLazyBufInit which is used only by the head handler 2013-03-14 14:35:56 +09:00
Norman Maurer
fe66f33f42 Fix issue where the bytes/messages are forwarded to the wrong handler 2013-03-12 08:37:27 +01:00
Trustin Lee
526dafca75 Fix checkstyle 2013-03-07 16:13:44 +09:00
Norman Maurer
88cc8c1739 [#1065] Provide Future/Promise without channel reference 2013-03-07 07:21:37 +01:00
Trustin Lee
148abe52f9 Reduce the amount of memory used for handler names
- Fixes #1123
2013-03-07 12:43:16 +09:00
Norman Maurer
256c931db2 Move exceptionCaught(..) back to ChannelHandler. Related to [#1118] 2013-03-05 07:34:34 +01:00
Trustin Lee
0e3825899a Move DefaultChannelPipeline.notifyHandlerException() to DefaultChannelHandlerContext / Always trigger exceptionCaught() at the handler that raised an exception
- Related: #1118
2013-03-05 12:13:14 +09:00
Norman Maurer
1603d9792d Move methods from ChannelHandler to ChannelStateHandler like proposed in [#1107] 2013-03-04 07:28:10 +01:00
Trustin Lee
f67441354a Move logging classes from internal to internal.logging
.. because internal is crowded
2013-02-26 14:54:25 -08:00
Norman Maurer
12b392b4cc Revert "[#1058] Add Channel/ChannelHandlerContext/ChannelPipeline.isWritable()"
This reverts commit 4e36fbca58138447dab10d69933b1633938640b3.
2013-02-22 14:42:32 +01:00