Skip to content

Commit

Permalink
finagle-netty4: Avoid NoClassDefFoundError if netty-transport-native-…
Browse files Browse the repository at this point in the history
…epoll is excluded

Problem

Currently Finagle fails at startup when netty-transport-native-epoll is not
available on the classpath.  Even on OS X, or if epoll is explicitly disabled.
(If I have seen correctly it is even disabled by default here:
finagle/finagle-netty4/src/main/resources/com/twitter/toggles/configs/com.twitter.finagle.netty4.json

Lines 3 to 7 in 835b6c3
   "id": "com.twitter.finagle.netty4.UseNativeEpollV2", "description": "Enable
   native epoll transport for netty4. Requires linux-x86_64", "fraction": 0.0
)

Solution

The solution is to move the creation of the different EventLoopGroups into own
methods with an explicit type signature returning just EventLoopGroup.

Result

As a result it should be possible to exclude netty-transport-native-epoll from
the classpath and therefore reduce the size of the bundle.

Side note: I see that I didn't add any tests. Unfortunately my sbt know how is
not existing, so I don't know how to set up separate tests with different
dependencies.

Signed-off-by: Isabel Martin <imartin@twitter.com>

JIRA Issues: CSL-6407

Differential Revision: https://phabricator.twitter.biz/D172924
  • Loading branch information
robertpanzer authored and jenkins committed May 21, 2018
1 parent 6534e45 commit 940809a
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 11 deletions.
3 changes: 3 additions & 0 deletions CHANGES
Expand Up @@ -27,6 +27,9 @@ Bug Fixes
ServicePerEndpoint. It can be set via `c.t.f.thrift.RichClientParam` or a `with`-method
as `Thrift{Mux}.client.withPerEndpointStats`. ``PHAB_ID=D169427``

* finagle-netty4: Avoid NoClassDefFoundError if netty-transport-native-epoll is not available
on the classpath.

18.5.0
-------

Expand Down
Expand Up @@ -47,6 +47,16 @@ private class ListeningServerBuilder(
// netty4 params
private[this] val param.Allocator(allocator) = params[param.Allocator]

private[ListeningServerBuilder] def mkEpollEventLoopGroup(): EventLoopGroup =
new EpollEventLoopGroup(
1 /*nThreads*/,
new NamedPoolThreadFactory("finagle/netty4/boss", makeDaemons = true))

private[ListeningServerBuilder] def mkNioEventLoopGroup(): EventLoopGroup =
new NioEventLoopGroup(
1 /*nThreads*/,
new NamedPoolThreadFactory("finagle/netty4/boss", makeDaemons = true))

/**
* Listen for connections and apply the `serveTransport` callback on
* connected [[Transport transports]].
Expand All @@ -62,15 +72,9 @@ private class ListeningServerBuilder(
new ListeningServer with CloseAwaitably {
private[this] val bossLoop: EventLoopGroup =
if (nativeEpoll.enabled)
new EpollEventLoopGroup(
1 /*nThreads*/,
new NamedPoolThreadFactory("finagle/netty4/boss", makeDaemons = true)
)
mkEpollEventLoopGroup()
else
new NioEventLoopGroup(
1 /*nThreads*/,
new NamedPoolThreadFactory("finagle/netty4/boss", makeDaemons = true)
)
mkNioEventLoopGroup()

private[this] val bootstrap = new ServerBootstrap()
if (nativeEpoll.enabled)
Expand Down
Expand Up @@ -19,10 +19,9 @@ import java.util.concurrent.{Executor, Executors}
* more granularly (e.g. [[com.twitter.util.FuturePool]] is a good tool for this).
*/
case class WorkerPool(eventLoopGroup: EventLoopGroup) {

def this(executor: Executor, numWorkers: Int) = this(
if (nativeEpoll.enabled) new EpollEventLoopGroup(numWorkers, executor)
else new NioEventLoopGroup(numWorkers, executor))
if (nativeEpoll.enabled) WorkerPool.mkEpollEventLoopGroup(numWorkers, executor)
else WorkerPool.mkNioEventLoopGroup(numWorkers, executor))

def mk() : (WorkerPool, Stack.Param[WorkerPool]) =
(this, WorkerPool.workerPoolParam)
Expand All @@ -38,4 +37,11 @@ object WorkerPool {
new WorkerPool(Executors.newCachedThreadPool(new BlockingTimeTrackingThreadFactory(
new NamedPoolThreadFactory("finagle/netty4", makeDaemons = true)
)), numWorkers()))

private[netty4] def mkEpollEventLoopGroup(numWorkers: Int, executor: Executor): EventLoopGroup =
new EpollEventLoopGroup(numWorkers, executor)

private[netty4] def mkNioEventLoopGroup(numWorkers: Int, executor: Executor): EventLoopGroup =
new NioEventLoopGroup(numWorkers, executor)

}

0 comments on commit 940809a

Please sign in to comment.