14158070bf
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. |
||
---|---|---|
.. | ||
src | ||
pom.xml | ||
README.md |
info
this module build will fail if any dependencies are not osgi bundles
http://en.wikipedia.org/wiki/OSGi#Bundles
on failure, build log will show error message similar to the following: (org.rxtx/rxtx/2.1.7 is not osgi bundle)
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running io.netty.verify.osgi.IT
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="netty-verify-osgi-deps">
<feature name="netty-verify-osgi-deps" version="4.0.0.Beta1-SNAPSHOT" description="Netty/Verify/OSGi/Deps">
<details>verify osgi compliance: all transitive dependencies are osgi bundles</details>
<bundle>mvn:io.netty/netty-buffer/4.0.0.Beta1-SNAPSHOT</bundle>
<bundle>mvn:io.netty/netty-common/4.0.0.Beta1-SNAPSHOT</bundle>
<bundle>mvn:io.netty/netty-codec/4.0.0.Beta1-SNAPSHOT</bundle>
<bundle>mvn:io.netty/netty-transport/4.0.0.Beta1-SNAPSHOT</bundle>
<bundle>mvn:io.netty/netty-codec-http/4.0.0.Beta1-SNAPSHOT</bundle>
<bundle>mvn:io.netty/netty-handler/4.0.0.Beta1-SNAPSHOT</bundle>
<bundle>mvn:io.netty/netty-codec-socks/4.0.0.Beta1-SNAPSHOT</bundle>
<bundle>mvn:io.netty/netty-transport-rxtx/4.0.0.Beta1-SNAPSHOT</bundle>
<bundle>wrap:mvn:org.rxtx/rxtx/2.1.7</bundle>
<bundle>mvn:io.netty/netty-transport-sctp/4.0.0.Beta1-SNAPSHOT</bundle>
<bundle>mvn:io.netty/netty-transport-udt/4.0.0.Beta1-SNAPSHOT</bundle>
<bundle>mvn:com.barchart.udt/barchart-udt-bundle/2.2.0</bundle>
</feature>
</features>
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.038 sec <<< FAILURE!
verifyNoWrapProtocol(io.netty.verify.osgi.IT) Time elapsed: 0.014 sec <<< FAILURE!
java.lang.AssertionError: karaf feature.xml contains 'wrap:' protocol: some transitive dependencies are not osgi bundles
at org.junit.Assert.fail(Assert.java:93)
at io.netty.verify.osgi.IT.verifyNoWrapProtocol(IT.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)