|
@@ -337,10 +337,15 @@ extension GRPCChannel {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let enqueued = self.state.withLock { state in
|
|
|
|
|
|
|
+ let (enqueued, loadBalancer) = self.state.withLock { state in
|
|
|
state.enqueue(continuation: continuation, waitForReady: waitForReady, id: id)
|
|
state.enqueue(continuation: continuation, waitForReady: waitForReady, id: id)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if let loadBalancer = loadBalancer {
|
|
|
|
|
+ // Attempting to pick a subchannel will trigger a connect event if the subchannel is idle.
|
|
|
|
|
+ _ = loadBalancer.pickSubchannel()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// Not enqueued because the channel is shutdown or shutting down.
|
|
// Not enqueued because the channel is shutdown or shutting down.
|
|
|
if !enqueued {
|
|
if !enqueued {
|
|
|
let error = RPCError(code: .unavailable, message: "channel is shutdown")
|
|
let error = RPCError(code: .unavailable, message: "channel is shutdown")
|
|
@@ -896,20 +901,21 @@ extension GRPCChannel.StateMachine {
|
|
|
continuation: CheckedContinuation<LoadBalancer, any Error>,
|
|
continuation: CheckedContinuation<LoadBalancer, any Error>,
|
|
|
waitForReady: Bool,
|
|
waitForReady: Bool,
|
|
|
id: QueueEntryID
|
|
id: QueueEntryID
|
|
|
- ) -> Bool {
|
|
|
|
|
|
|
+ ) -> (enqueued: Bool, loadBalancer: LoadBalancer?) {
|
|
|
switch self.state {
|
|
switch self.state {
|
|
|
case .notRunning(var state):
|
|
case .notRunning(var state):
|
|
|
self.state = ._modifying
|
|
self.state = ._modifying
|
|
|
state.queue.append(continuation: continuation, waitForReady: waitForReady, id: id)
|
|
state.queue.append(continuation: continuation, waitForReady: waitForReady, id: id)
|
|
|
self.state = .notRunning(state)
|
|
self.state = .notRunning(state)
|
|
|
- return true
|
|
|
|
|
|
|
+ return (true, nil)
|
|
|
case .running(var state):
|
|
case .running(var state):
|
|
|
self.state = ._modifying
|
|
self.state = ._modifying
|
|
|
state.queue.append(continuation: continuation, waitForReady: waitForReady, id: id)
|
|
state.queue.append(continuation: continuation, waitForReady: waitForReady, id: id)
|
|
|
self.state = .running(state)
|
|
self.state = .running(state)
|
|
|
- return true
|
|
|
|
|
|
|
+ // If idle then return the current load balancer so that it can be told to start connecting.
|
|
|
|
|
+ return (true, state.connectivityState == .idle ? state.current : nil)
|
|
|
case .stopping, .stopped:
|
|
case .stopping, .stopped:
|
|
|
- return false
|
|
|
|
|
|
|
+ return (false, nil)
|
|
|
case ._modifying:
|
|
case ._modifying:
|
|
|
fatalError("Invalid state")
|
|
fatalError("Invalid state")
|
|
|
}
|
|
}
|