Commit Graph

98 Commits

Author SHA1 Message Date
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
fada776756 Refactor the aio transport to not depend on the AioChannelFinder and so not need for refelection 2013-02-22 06:53:33 +01:00
Norman Maurer
5370573400 Change ReferenceCounted.retain* to return itself and so allow method chaining 2013-02-14 07:39:44 +01: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
bf0bfe9a69 Fix inspector warnings 2013-02-11 16:52:43 +09:00
Norman Maurer
9228c97546 Tighten up visibility 2013-02-11 07:27:05 +01:00
Trustin Lee
b9996908b1 Implement reference counting
- Related: #1029
- Replace Freeable with ReferenceCounted
- Add AbstractReferenceCounted
- Add AbstractReferenceCountedByteBuf
- Add AbstractDerivedByteBuf
- Add EmptyByteBuf
2013-02-10 13:10:09 +09:00
Trustin Lee
b4eaedf712 Remove confusing ChannelState/OperationHandlerAdapter.inboundBufferUpdated/flush() implementation 2013-02-08 17:17:39 +09:00
Trustin Lee
fa1b49de98 More robust automatic messageType detection for ChannelInboundMessageHandlerAdapter and MessageToMessageDecoder 2013-02-08 15:45:17 +09:00
Trustin Lee
e5616c85c4 Automatic messageType detection for ChannelInboundMessageHandlerAdapter 2013-02-08 13:48:47 +09:00
Trustin Lee
d4742bbe16 Clean up abstract ChannelHandler impls / Remove ChannelHandlerContext.hasNext*()
- Rename ChannelHandlerAdapter to ChannelDuplexHandler
- Add ChannelHandlerAdapter that implements only ChannelHandler
- Rename CombinedChannelHandler to CombinedChannelDuplexHandler and
  improve runtime validation
- Remove ChannelInbound/OutboundHandlerAdapter which are not useful
- Make ChannelOutboundByteHandlerAdapter similar to
  ChannelInboundByteHandlerAdapter
- Make the tail and head handler of DefaultChannelPipeline accept both
  bytes and messages.  ChannelHandlerContext.hasNext*() were removed
  because they always return true now.
- Removed various unnecessary null checks.
- Correct method/field names:
  inboundBufferSuspended -> channelReadSuspended
2013-02-07 23:47:45 +09:00
Norman Maurer
86b4cde82f Make sure the inbound/outbound buffer of the ChannelHandlerContext is only modified within the EventLoop 2013-02-05 16:19:04 +01:00
Trustin Lee
2e44a1ba91 Fix test failures in SingleThreadEventLoopTest on Windows
- It seems like Windows sometimes sleeps less than specified.
- Related issue: #726
2013-02-05 16:27:37 +09:00
Norman Maurer
ade3cc1329 Move non socket specific stuff out of the socket package 2013-02-01 09:10:28 +01:00
Trustin Lee
788d7e9b8b Remove Bootstrap operations that require a promise and add various ad-hoc bind() and connect() operations
- Update examples to use the newly added bind() and connect()
  operations.
2013-01-30 20:11:00 +09:00
Norman Maurer
cc278d45c2 Disable test as this let fail the build 80% times on osx and slow linux servers. Need to investigate 2013-01-26 16:17:12 +01:00
Trustin Lee
eb337ff5a7 Fix various inspection warnings 2013-01-10 15:23:58 +09:00
Trustin Lee
b6fcf3acc4 Simplify DefaultChannelPipeline 2013-01-09 19:13:43 +09: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
Norman Maurer
26595471fb Call Freeable.free() if a Freeable message reaches the end of the ChannelPipeline to guard against resource leakage 2013-01-07 12:34:18 +01: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
Trustin Lee
def12a171c Rename ChannelBuf to Buf and ChannelBufType to BufType
- Fixes #825
2012-12-17 17:43:45 +09:00
Trustin Lee
03e68482bb Remove ChannelBuf/ByteBuf.Unsafe
- Fixes #826
Unsafe.isFreed(), free(), suspend/resumeIntermediaryAllocations() are not that dangerous. internalNioBuffer() and internalNioBuffers() are dangerous but it seems like nobody is using it even inside Netty. Removing those two methods also removes the necessity to keep Unsafe interface at all.
2012-12-17 17:41:21 +09:00
Trustin Lee
b47fc77522 Add PooledByteBufAllocator + microbenchmark module
This pull request introduces the new default ByteBufAllocator implementation based on jemalloc, with a some differences:

* Minimum possible buffer capacity is 16 (jemalloc: 2)
* Uses binary heap with random branching (jemalloc: red-black tree)
* No thread-local cache yet (jemalloc has thread-local cache)
* Default page size is 8 KiB (jemalloc: 4 KiB)
* Default chunk size is 16 MiB (jemalloc: 2 MiB)
* Cannot allocate a buffer bigger than the chunk size (jemalloc: possible) because we don't have control over memory layout in Java. A user can work around this issue by creating a composite buffer, but it's not always a feasible option. Although 16 MiB is a pretty big default, a user's handler might need to deal with the bounded buffers when the user wants to deal with a large message.

Also, to ensure the new allocator performs good enough, I wrote a microbenchmark for it and made it a dedicated Maven module. It uses Google's Caliper framework to run and publish the test result (example)

Miscellaneous changes:

* Made some ByteBuf implementations public so that those who implements a new allocator can make use of them.
* Added ByteBufAllocator.compositeBuffer() and its variants.
* ByteBufAllocator.ioBuffer() creates a buffer with 0 capacity.
2012-12-13 22:35:06 +09:00
Norman Maurer
9d42acbc2a [#803] Make sure the right EventExecutor is used after re-register a Channel to another EventLoop 2012-12-13 10:38:44 +01:00
Trustin Lee
321b18d4d1 Fix test failures n LocalTransportThreadModelTest
testConcurrentMessageBufferAccess() assumes the outbound/inbound byte buffers are unbounded.  Because PooledByteBuf is bounded, the test did not pass.

The fix makes an assumption that ctx.flush() or fireInboundBufferUpdated() will make the next buffer consumed immediately, which is not the case in the real world.  Under network congestion, a user will see IndexOutOfBoundsException if the user's handler implementation writes boundlessly into inbound/outbound buffers.
2012-12-10 16:38:20 +01: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
00c4b944e4 Fix more inspector warnings introduced by recent mergences 2012-12-01 00:10:42 +09:00
Trustin Lee
6208c62888 Fix inspector warnings introduced by recent mergences 2012-11-30 23:01:57 +09:00
Trustin Lee
dbbc6ad73f Reduce the chance of RejectedExecutionException
When a Netty application shuts down, a user often sees a REE
(RejectedExecutionException).

A REE is raised due to various reasons we don't have control over, such
as:

- A client connects to a server while the server is shutting down.

- An event is triggered for a closed Channel while its event loop is
  also shutting down.  Some of them are:
  - channelDeregistered (triggered after a channel is closed)
  - freeIn/OutboundBuffer (triggered after channelDeregistered)
  - userEventTriggered (triggered anytime)

To address this issue, a new method called confirmShutdown() has been
added to SingleThreadEventExecutor.  After a user calls shutdown(),
confirmShutdown() runs any remaining tasks in the task queue and ensures
no events are triggered for last 2 seconds.  If any task are added to
the task queue before 2 seconds passes, confirmShutdown() prevents the
event loop from terminating by returning false.

Now that SingleThreadEventExecutor needs to accept tasks even after
shutdown(), its execute() method only rejects the task after the event
loop is terminated (i.e. isTerminated() returns true.)  Except that,
there's no change in semantics.

SingleThreadEventExecutor also checks if its subclass called
confirmShutdown() in its run() implementation, so that Netty developers
can make sure they shut down their event loop impementation correctly.

It also fixes a bug in AioSocketChannel, revealed by delayed shutdown,
where an inboundBufferUpdated() event is triggered on a closed Channel
with deallocated buffers.

Caveats:

Because SingleThreadEventExecutor.takeTask() does not have a notion of
timeout, confirmShutdown() adds a dummy task (WAKEUP_TASK) to wake up
takeTask() immediately and instead sleeps hard-coded 100ms.  I'll
address this issue later by modifying takeTask() times out dynamically.

Miscellaneous changes:

SingleThreadEventExecutor.wakeup() now has the default implementation.
Instead of interrupting the current thread, it simply adds a dummy task
(WAKEUP_TASK) to the task queue, which is more elegant and efficient.
NioEventLoop is the only implementation that overrides it. All other
implementations' wakeup()s were removed thanks to this change.
2012-11-22 20:36:13 +01: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
Evans Yang
a0da613e86 [#743] Make the "tail" point to the last channel handler context. And add several cases for DefaultChannelPipeline. 2012-11-16 07:33:32 +01:00
Trustin Lee
36c8eb02e8 Fix parameter namings + some more 2012-11-12 12:59:37 +09:00
Trustin Lee
6f2840193a Fix inspection warnings related with JUnit usage 2012-11-12 12:45:06 +09:00
Trustin Lee
9746bb2036 Make a member field final wherever possible 2012-11-12 09:43:55 +09:00
Trustin Lee
aa7cd691df Remove redundant 'else' branches. 2012-11-12 09:31:40 +09:00
Trustin Lee
b4f796c5e3 Use 'x' over "x" wherever possible / String.equals("") -> isEmpty() 2012-11-10 08:03:52 +09:00
Trustin Lee
f77f13faf0 Make classes static wherever possible 2012-11-10 07:32:53 +09:00
Trustin Lee
5c57dd9f0d Remove redundant field initialization 2012-11-10 06:56:39 +09:00
Norman Maurer
da7bcfa8f6 Add tests for AioChannelFinder implementations 2012-10-01 06:46:55 +02:00
Trustin Lee
256f55b2e9 [#608] Channel MessageBridge concurrency issues
Fixed ArrayIndexOutOfBoundsException caused by a race condition that the peer's inbound buffer is accessed concurrently.
2012-09-22 11:22:02 +09:00
norman
df72356d7d Rename classes as result of descussion on #594 2012-09-12 14:04:41 +02:00
Norman Maurer
4ce85827ed Start to refactor bootstraps to share more code and allow for reuse 2012-09-11 08:31:20 +02:00
Trustin Lee
ebf33c6e3b No need to make the timeout of thread model test too long
Using m1.large instance fixed the unstable build problem with CloudBees
2012-08-19 15:18:51 +09:00
Trustin Lee
7b213d2c93 Double the timeout of LocalTransportThreadModelTest
- because it seems to make the build unstable in CloudBees
2012-08-19 15:12:18 +09:00
Trustin Lee
8bfbebc772 Rename TaskScheduler to ChannelTaskScheduler 2012-08-19 15:10:09 +09:00
Trustin Lee
11c742f392 [#59] Make ChannelFuture implement Future<Void> 2012-08-18 22:53:58 +09:00
Trustin Lee
421eabe666 [#473] Fix elevated context switching in SingleThreadEventExecutor
- Remove polling in SingleThreadEventExecutor
- Create a dedicated scheduled task scheduler called 'TaskScheduler'
- TaskScheduler is created per EventLoopGroup / EventExecutorGroup
- SingleThreadEventExecutor delegates all scheduled execution requests
  to TaskScheduler provided as a constructor parameter
- TaskScheduler is a specialized form of single threaded 
  ScheduledExecutorService which requires an EventExecutor as a
  parameter for all requests.
2012-08-18 18:40:21 +09:00
Trustin Lee
d3a2835503 Add ServerBootstrap.group() that takes a single group 2012-08-10 20:26:04 +09:00