Skip to content

Commit dc5f647

Browse files
Ivan Gorbachevjenkins
Ivan Gorbachev
authored and
jenkins
committed
finagle-netty4: Add epollEventLoopGroupClassName flag
Problem We need to be able to use custom implementation of event loop, e.g. with additional logging or metrics. Solution Add com.twitter.finagle.netty4.epollEventLoopGroupClassName flag. It specifies the full classname that should be used instead of default netty implementation. JIRA Issues: STOR-8478 Differential Revision: https://phabricator.twitter.biz/D1185136
1 parent 744e0ae commit dc5f647

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

CHANGELOG.rst

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ New Features
2828
* finagle-mysql: Added support for LONG_BLOB data type. ``PHAB_ID=D1152247``
2929
* finagle-mux: Added a stat, <server_label>/mux/request_context_bytes, that shows the size of the received
3030
context per request.
31+
* finagle-netty4: Added support for custom event loop implementations. ``PHAB_ID=D1185136``
3132

3233

3334
Bug Fixes

finagle-netty4/src/main/scala/com/twitter/finagle/netty4/WorkerEventLoop.scala

+22-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.twitter.finagle.netty4
22

33
import com.twitter.finagle.stats.FinagleStatsReceiver
44
import com.twitter.finagle.util.BlockingTimeTrackingThreadFactory
5+
import com.twitter.util.logging.Logger
56
import io.netty.channel.EventLoopGroup
67
import io.netty.channel.epoll.Epoll
78
import io.netty.channel.epoll.EpollEventLoopGroup
@@ -19,6 +20,8 @@ import java.util.concurrent.ThreadFactory
1920
*/
2021
private object WorkerEventLoop {
2122

23+
private[this] val log = Logger.getLogger(getClass.getName)
24+
2225
private[this] val workerPoolSize = new AtomicInteger(0)
2326

2427
private[this] val eventLoopGroups = ConcurrentHashMap.newKeySet[EventLoopGroup]()
@@ -63,15 +66,27 @@ private object WorkerEventLoop {
6366

6467
def make(executor: Executor, numWorkers: Int, ioRatio: Int = 50): EventLoopGroup = {
6568
workerPoolSize.addAndGet(numWorkers)
66-
val result =
67-
if (useNativeEpoll() && Epoll.isAvailable) {
68-
val group = new EpollEventLoopGroup(numWorkers, executor)
69-
group.setIoRatio(ioRatio)
70-
group
71-
} else {
72-
new NioEventLoopGroup(numWorkers, executor)
69+
val result = if (epollEventLoopGroupClassName().nonEmpty) {
70+
val clz = Class.forName(epollEventLoopGroupClassName())
71+
val eventLoopGroup = clz
72+
.getConstructor(classOf[Int], classOf[Executor])
73+
.newInstance(java.lang.Integer.valueOf(numWorkers), executor)
74+
try {
75+
val setIoRatioMethod = clz.getMethod("setIoRatio", classOf[Int])
76+
setIoRatioMethod.invoke(eventLoopGroup, java.lang.Integer.valueOf(ioRatio))
77+
} catch {
78+
case _: NoSuchMethodException | _: SecurityException => // no-op
7379
}
80+
eventLoopGroup.asInstanceOf[EventLoopGroup]
81+
} else if (useNativeEpoll() && Epoll.isAvailable) {
82+
val group = new EpollEventLoopGroup(numWorkers, executor)
83+
group.setIoRatio(ioRatio)
84+
group
85+
} else {
86+
new NioEventLoopGroup(numWorkers, executor)
87+
}
7488

89+
log.info(s"Created event loop group: ${result.getClass.getName}")
7590
eventLoopGroups.add(result)
7691

7792
result
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.twitter.finagle.netty4
2+
3+
import com.twitter.app.GlobalFlag
4+
5+
/**
6+
* Create custom EventLoopGroup instead of default EpollEventLoopGroup or NioEventLoopGroup.
7+
* This can be useful to run alternative implementations, e.g. with additional instrumentation.
8+
* The provided value must be full class name, e.g. io.netty.channel.epoll.EpollEventLoopGroup,
9+
* which implements io.netty.channel.MultithreadEventLoopGroup
10+
*/
11+
private object epollEventLoopGroupClassName
12+
extends GlobalFlag[String]("", "Create custom EventLoopGroup")

0 commit comments

Comments
 (0)