Browse Source

Avoid the possibility of making outcalls in 'ClientCallTransport' before updating internal state (#970)

Motivation:

A scheduled task being executed or cancelled may have arbitrary side
effects. In 'ClientCallTransport' when we receive a 'status' we cancel a
scheduled task before updating our internal state.

Modifications:

Transition to closed before cancelling the timeout.

Result:

Resolves #961
George Barnett 5 years ago
parent
commit
8a93dc1c3f
1 changed files with 4 additions and 4 deletions
  1. 4 4
      Sources/GRPC/ClientCalls/ClientCallTransport.swift

+ 4 - 4
Sources/GRPC/ClientCalls/ClientCallTransport.swift

@@ -545,14 +545,14 @@ extension ChannelTransport: ClientCallInbound {
         self.responseContainer.lazyTrailingMetadataPromise.succeed(metadata)
         self.responseContainer.lazyTrailingMetadataPromise.succeed(metadata)
 
 
       case let .status(status):
       case let .status(status):
-        // We're done; cancel the timeout.
-        self.scheduledTimeout?.cancel()
-        self.scheduledTimeout = nil
-
         // We're closed now.
         // We're closed now.
         self.state = .closed
         self.state = .closed
         self.stopTimer(status: status)
         self.stopTimer(status: status)
 
 
+        // We're done; cancel the timeout.
+        self.scheduledTimeout?.cancel()
+        self.scheduledTimeout = nil
+
         // We're not really failing the status here; in some cases the server may fast fail, in which
         // We're not really failing the status here; in some cases the server may fast fail, in which
         // case we'll only see trailing metadata and status: we should fail the initial metadata and
         // case we'll only see trailing metadata and status: we should fail the initial metadata and
         // response in that case.
         // response in that case.