70 Commits

Author SHA1 Message Date
Michael Nitschinger
299ce22938 Fix typo in EmbeddedSocketAddress. 2014-01-02 15:34:15 +01:00
Trustin Lee
94d6e44bba Change the return type of EmbeddedChannel.read*() from Object to an ad-hoc type parameter
.. so that there's no need to explicitly down-cast.

Fixes #2067
2013-12-16 22:22:47 +09:00
Trustin Lee
110745b0eb Remove the distinction of inbound handlers and outbound handlers
- Fixes #1808
- Move all methods in ChannelInboundHandler and ChannelOutboundHandler up to ChannelHandler
- Remove ChannelInboundHandler and ChannelOutboundHandler
- Deprecate ChannelInboundHandlerAdapter, ChannelOutboundHandlerAdapter, and ChannelDuplexHandler
- Replace CombinedChannelDuplexHandler with ChannelHandlerAppender
  because it's not possible to combine two handlers into one easily now
- Introduce 'Skip' annotation to pass events through efficiently
- Remove all references to the deprecated types and update Javadoc
2013-11-27 17:31:28 +09:00
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
daf15fc167 Don't create an EmbeddedSocketAddress every time 2013-11-08 18:01:29 +09:00
Trustin Lee
9097fce9e3 Allow empty handler list when creating a new EmbeddedChannel
.. so that it can be used for dynamically initialized pipelines

- Fixes #1899
2013-10-08 17:18:41 +09:00
Bill Gallagher
e743a27e75 Pass eventLoop and childEventLoopGroup as Channel constructor parameters
- Add ServerChannelFactory for ServerBootstrap which is the counterpart
  of ChannelFactory for Bootstrap
2013-10-08 17:03:50 +09:00
Bill Gallagher
f80109f423 use enum for state in EmbeddedChannel 2013-10-01 21:08:45 +02:00
Norman Maurer
6716dca17a Use a Thread-local based direct buffer pool if non pooled allocator is used 2013-09-05 11:58:03 +02:00
Norman Maurer
80d30c3dd8 Small code improvements 2013-08-26 07:52:47 +02:00
Norman Maurer
e09aea5902 Rename methods of EmbeddedChannel and mark old ones as @deprecated 2013-07-31 16:04:08 +09:00
Jeff Pinner
bf2430d255 Change AbstractChannel#doRegister return type from Runnable to void. 2013-07-27 20:22:02 +02:00
Jeff Pinner
ca59c1201e Change AbstractChannel#doDeregister return type from Runnable to void. 2013-07-26 22:21:41 +02:00
Trustin Lee
bcef796dc7 Rewrite ChannelOutboundBuffer
- Merge MessageList into ChannelOutboundBuffer
- Make ChannelOutboundBuffer a queue-like data structure so that it is nearly impossible to leak a message
- Make ChannelOutboundBuffer public so that AbstractChannel can expose it to its subclasses.
- TODO: Re-enable gathering write in NioSocketChannel
2013-07-18 20:59:14 +09:00
Norman Maurer
c20c852602 More javadoc fixes 2013-07-14 18:04:33 +02: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
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
7396f9f2b2 Remove Channel.id completely / Use 64-bit hashCode internally to reduce the chance of collision in compareTo() 2013-07-09 14:49:06 +09:00
Norman Maurer
bfc9c6d80d Add ChannelInboundConsumingHandler
..which is useful when the handler is placed at the last position of the
pipeline because it releases the received messages automatically.
2013-06-25 11:07:14 +09:00
Trustin Lee
79e236dfc2 Make EventExecutor.shutdownGracefully() return Future
- Also added EventExecutor.terminationFuture()
- Also fixed type signature problem with Future.add/removeListener()
- Related issue: #1389
2013-06-12 08:00:54 +09: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
Trustin Lee
23d0178494 Introduce EventExecutor.shutdownGracefully() that deprecates shutdown()
shutdownGracefully() provides two optional parameters that give more
control over when an executor has to be shut down.

- Related issue: #1307
- Add shutdownGracefully(..) and isShuttingDown()
- Deprecate shutdown() / shutdownNow()
- Replace lastAccessTime with lastExecutionTime and update it after task
  execution for accurate quiet period check
  - runAllTasks() and runShutdownTasks() update it automatically.
  - Add updateLastExecutionTime() so that subclasses can update it
- Add a constructor parameter that tells not to add an unncessary wakeup
  task in execute() if addTask() wakes up the executor thread
  automatically.  Previously, execute() always called wakeup() after
  addTask(), which often caused an extra dummy task in the task queue.
- Use shutdownGracefully() wherever possible / Deprecation javadoc
- Reduce the running time of SingleThreadEventLoopTest from 40s to 15s
  using custom graceful shutdown parameters

- Other changes made along with this commit:
  - takeTask() does not throw InterruptedException anymore.
    - Returns null on interruption or wakeup
  - Make sure runShutdownTasks() return true even if an exception was
    raised while running the shutdown tasks
  - Remove unnecessary isShutdown() checks
  - Consistent use of SingleThreadEventExecutor.nanoTime()

Replace isWakeupOverridden with a constructor parameter
2013-05-01 10:52:38 +09: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
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
fa02ffddae Remove TaskScheduler and ImmediateEventExecutor that requires TaskScheduler
- Related issue: #817
2013-03-22 09:06:08 +09:00
Norman Maurer
ce87b627be Let EventExecutor return our Future to allow the user to work also with FutureListener here. Also add a special ScheduledFuture that extends our Future for this purpose. 2013-03-19 10:45:42 +01:00
Trustin Lee
70a51bcd8d Fix memory leak in AbstractEmbeddedChannel
- Allow a transport implementation to perform an arbitrary task when a channel has been deregistered completely
2013-03-14 15:51:33 +09:00
Norman Maurer
88cc8c1739 [#1065] Provide Future/Promise without channel reference 2013-03-07 07:21:37 +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
Trustin Lee
b4f4b95739 Move io.netty.logging to io.netty.internal / Move Signal out of internal because we use it in Channel*MessageAdapters 2013-02-11 20:08:18 +09:00
Trustin Lee
61bbb04852 Fix a bug in AbstractEmbeddedChannel where flush failure is not recorded 2013-02-10 00:46:30 +09:00
Trustin Lee
2ec932798f Replace .readable() and .writable() to .isReadable() and .isWritable() 2013-01-31 18:24:33 +01:00
Norman Maurer
ec013bf2d3 [#983] Force the user to implement an actual ChannelInboundHandler or ChannelOutboundHandler
For this ChannelInboundHandler* and ChannelOutboundHandler* was made package private
2013-01-31 15:50:27 +01:00
Trustin Lee
dd6b7969b7 Give a handler more control over how its buffers' read bytes are discarded.
This pull request adds two new handler methods: discardInboundReadBytes(ctx) and discardOutboundReadBytes(ctx) to ChannelInboundByteHandler and ChannelOutboundByteHandler respectively. They are called between every inboundBufferUpdated() and flush() respectively. Their default implementation is to call discardSomeReadBytes() on their buffers and a user can override this behavior easily. For example, ReplayingDecoder.discardInboundReadBytes() looks like the following:

    @Override
    public void discardInboundReadBytes(ChannelHandlerContext ctx) throws Exception {
        ByteBuf in = ctx.inboundByteBuffer();
        final int oldReaderIndex = in.readerIndex();
        super.discardInboundReadBytes(ctx);
        final int newReaderIndex = in.readerIndex();
        checkpoint -= oldReaderIndex - newReaderIndex;
    }

If a handler, which has its own buffer index variable, extends ReplayingDecoder or ByteToMessageDecoder, the handler can also override discardInboundReadBytes() and adjust its index variable accordingly.
2013-01-09 13:34:09 +09:00
Trustin Lee
103edc4467 Make ChannelConfig.setAutoRead() triggers Channel.read() if autoRead was previously false
- also rename JDK socket and channel variables so that they are less ambiguous
2013-01-01 16:49:21 +09:00
Norman Maurer
4e77bacdf7 [#873] [#868] Split ChannelFuture into ChannelFuture and ChannelPromise 2012-12-31 23:27:16 +09:00
Trustin Lee
0909878581 Read only when requested (read-on-demand)
This pull request introduces a new operation called read() that replaces the existing inbound traffic control method. EventLoop now performs socket reads only when the read() operation has been issued. Once the requested read() operation is actually performed, EventLoop triggers an inboundBufferSuspended event that tells the handlers that the requested read() operation has been performed and the inbound traffic has been suspended again. A handler can decide to continue reading or not.

Unlike other outbound operations, read() does not use ChannelFuture at all to avoid GC cost. If there's a good reason to create a new future per read at the GC cost, I'll change this.

This pull request consequently removes the readable property in ChannelHandlerContext, which means how the traffic control works changed significantly.

This pull request also adds a new configuration property ChannelOption.AUTO_READ whose default value is true. If true, Netty will call ctx.read() for you. If you need a close control over when read() is called, you can set it to false.

Another interesting fact is that non-terminal handlers do not really need to call read() at all. Only the last inbound handler will have to call it, and that's just enough. Actually, you don't even need to call it at the last handler in most cases because of the ChannelOption.AUTO_READ mentioned above.

There's no serious backward compatibility issue. If the compiler complains your handler does not implement the read() method, add the following:

public void read(ChannelHandlerContext ctx) throws Exception {
    ctx.read();
}

Note that this pull request certainly makes bounded inbound buffer support very easy, but itself does not add the bounded inbound buffer support.
2012-12-31 23:26:00 +09:00
Norman Maurer
ef555d268c Add more javadocs and replace some abstract methods with noops as we often implemented them as noops 2012-12-21 17:06:24 +01:00
Norman Maurer
e4ed551490 Move shared methods to the AbstractEmbeddedChannel class and add javadocs 2012-12-21 10:41:27 +01:00
Trustin Lee
e59ac8e79b Do not call inbound event methods directly
- Fixes #831

This commit ensures the following events are never triggered as a direct
invocation if they are triggered via ChannelPipeline.fire*():

- channelInactive
- channelUnregistered
- exceptionCaught

This commit also fixes the following issues surfaced by this fix:

- Embedded channel implementations run scheduled tasks too early
- SpdySessionHandlerTest tries to generate inbound data even after the
  channel is closed.
- AioSocketChannel enters into an infinite loop on I/O error.
2012-12-18 03:04:26 +09:00
Trustin Lee
def12a171c Rename ChannelBuf to Buf and ChannelBufType to BufType
- Fixes #825
2012-12-17 17:43:45 +09:00
Trustin Lee
51e6519b67 Replace UnsafeByteBuf with ByteBuf.unsafe() again
* UnsafeByteBuf is gone. I added ByteBuf.unsafe() back.
* To avoid extra instantiation, all ByteBuf implementations implement the ByteBuf.Unsafe interface.
* To hide this implementation detail, all ByteBuf implementations are package-private.
* AbstractByteBuf and SwappedByteBuf are public and they do not implement ByteBuf.Unsafe because they don't need to.
* unwrap() is not an unsafe operation anymore.
* ChannelBuf also has unsafe() and Unsafe. ByteBuf.Unsafe extends ChannelBuf.unsafe(). ChannelBuf.unsafe() provides free() operation so that a user does not need to down-cast the buffer in freeInbound/OutboundBuffer().
2012-12-05 19:28:56 +09:00
Trustin Lee
81e2db10fa ByteBufAllocator API w/ ByteBuf perf improvements
This commit introduces a new API for ByteBuf allocation which fixes
issue #643 along with refactoring of ByteBuf for simplicity and better
performance. (see #62)

A user can configure the ByteBufAllocator of a Channel via
ChannelOption.ALLOCATOR or ChannelConfig.get/setAllocator().  The
default allocator is currently UnpooledByteBufAllocator.HEAP_BY_DEFAULT.

To allocate a buffer, do not use Unpooled anymore. do the following:

  ctx.alloc().buffer(...); // allocator chooses the buffer type.
  ctx.alloc().heapBuffer(...);
  ctx.alloc().directBuffer(...);

To deallocate a buffer, use the unsafe free() operation:

  ((UnsafeByteBuf) buf).free();

The following is the list of the relevant changes:

- Add ChannelInboundHandler.freeInboundBuffer() and
  ChannelOutboundHandler.freeOutboundBuffer() to let a user free the
  buffer he or she allocated. ChannelHandler adapter classes implement
  is already, so most users won't need to call free() by themselves.
  freeIn/OutboundBuffer() methods are invoked when a Channel is closed
  and deregistered.

- All ByteBuf by contract must implement UnsafeByteBuf. To access an
  unsafe operation: ((UnsafeByteBuf) buf).internalNioBuffer()

- Replace WrappedByteBuf and ByteBuf.Unsafe with UnsafeByteBuf to
  simplify overall class hierarchy and to avoid unnecesary instantiation
  of Unsafe instances on an unsafe operation.

- Remove buffer reference counting which is confusing

- Instantiate SwappedByteBuf lazily to avoid instantiation cost

- Rename ChannelFutureFactory to ChannelPropertyAccess and move common
  methods between Channel and ChannelHandlerContext there. Also made it
  package-private to hide it from a user.

- Remove unused unsafe operations such as newBuffer()

- Add DetectionUtil.canFreeDirectBuffer() so that an allocator decides
  which buffer type to use safely
2012-11-22 15:10:59 +09:00
Trustin Lee
d298707198 [#502] Split EventLoop/EventExecutor into parent and children
- Add EventExecutorGroup and EventLoopGroup
- EventExecutor and EventLoop extends EventExecutorGroup and
  EventLoopGroup
  - They form their own group so that .next() returns itself.
- Rename Bootstrap.eventLoop() to group()
- Rename parameter names such as executor to group
- Rename *EventLoop/Executor to *EventLoop/ExecutorGroup
- Rename *ChildEventLoop/Executor to *EventLoop/Executor
2012-08-10 20:17:18 +09:00
Norman Maurer
57e7255566 Add support to suspend reads. See #71 2012-07-27 20:02:47 +02:00
Trustin Lee
5a613f379e Make ByteBuf dynamic / Introduce an interface for composite buffers
- Replace ByteBufferBackedByteBuf with DirectByteBuf
- Make DirectByteBuf and HeapByteBuf dynamic
- Remove DynamicByteBuf
- Replace Unpooled.dynamicBuffer() with Unpooled.buffer() and
  directBuffer()
- Remove ByteBufFactory (will be replaced with ByteBufPool later)
- Add ByteBuf.Unsafe (might change in the future)
2012-07-19 20:25:47 +09:00
Trustin Lee
42380b54b3 Revert file mode 2012-07-07 14:39:35 +09:00