瀏覽代碼

Break timer retain cycle (#85)

Motivation:

The timers used by the client/server connection management hanlders
indirectly hold references to the underlying handler. The hanlder holds
a reference to the timer. This cycle isn't broken so a handler is leaked
for each connection.

Modifications:

- Nil out the timers to break the retain cycle when the channel becomes
inactive

Result:

- Fewer leaks
- Resolves #84
George Barnett 8 月之前
父節點
當前提交
9bd1b5b5e3

+ 7 - 0
Sources/GRPCNIOTransportCore/Client/Connection/ClientConnectionHandler.swift

@@ -160,7 +160,14 @@ package final class ClientConnectionHandler: ChannelInboundHandler, ChannelOutbo
     }
 
     self.keepaliveTimerHandler?.cancel()
+    self.keepaliveTimerHandler = nil
+
     self.keepaliveTimeoutHandler?.cancel()
+    self.keepaliveTimeoutHandler = nil
+
+    self.maxIdleTimerHandler?.cancel()
+    self.maxIdleTimerHandler = nil
+
     context.fireChannelInactive()
   }
 

+ 10 - 0
Sources/GRPCNIOTransportCore/Server/Connection/ServerConnectionManagementHandler.swift

@@ -295,10 +295,20 @@ package final class ServerConnectionManagementHandler: ChannelDuplexHandler {
 
   package func channelInactive(context: ChannelHandlerContext) {
     self.maxIdleTimerHandler?.cancel()
+    self.maxAgeTimerHandler = nil
+
     self.maxAgeTimerHandler?.cancel()
+    self.maxAgeTimerHandler = nil
+
     self.maxGraceTimerHandler?.cancel()
+    self.maxGraceTimerHandler = nil
+
     self.keepaliveTimerHandler?.cancel()
+    self.keepaliveTimerHandler = nil
+
     self.keepaliveTimeoutHandler?.cancel()
+    self.keepaliveTimeoutHandler = nil
+
     context.fireChannelInactive()
   }