Skip to content

Commit 289c0bc

Browse files
authored
Reset go away state (#49)
Motivation: The pick first load balancer keeps track of whether the current subchannel is going away. This is done so that if there isn't yet a subchannel to roll over too it won't be offered up when the GRPCChannel asks for a subchannel. However, this state wasn't reset in enough places within the state machine. Modifications: - Reset the is-going-away state when updating the current subchannel and when the current subchannel becomes idle Result: Resolves #40
1 parent 514de49 commit 289c0bc

File tree

2 files changed

+9
-0
lines changed

2 files changed

+9
-0
lines changed

Sources/GRPCNIOTransportCore/Client/Connection/LoadBalancers/PickFirstLoadBalancer.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ extension PickFirstLoadBalancer.State.Active {
328328
if self.connectivityState == .idle {
329329
// Current subchannel is idle and we have a new endpoint, move straight to the new
330330
// subchannel.
331+
self.isCurrentGoingAway = false
331332
self.current = newSubchannel
332333
self.parked[current.id] = current
333334
onUpdateEndpoint = .connect(newSubchannel, close: current)
@@ -345,10 +346,12 @@ extension PickFirstLoadBalancer.State.Active {
345346
onUpdateEndpoint = .connect(newSubchannel, close: next)
346347

347348
case (.none, .none):
349+
self.isCurrentGoingAway = false
348350
self.current = newSubchannel
349351
onUpdateEndpoint = .connect(newSubchannel, close: nil)
350352

351353
case (.none, .some(let next)):
354+
self.isCurrentGoingAway = false
352355
self.current = newSubchannel
353356
self.next = nil
354357
self.parked[next.id] = next
@@ -368,6 +371,10 @@ extension PickFirstLoadBalancer.State.Active {
368371
if connectivityState == self.connectivityState {
369372
onUpdate = .none
370373
} else {
374+
// If the subchannel was going away and became idle then it went away.
375+
if connectivityState == .idle {
376+
self.isCurrentGoingAway = false
377+
}
371378
self.connectivityState = connectivityState
372379
onUpdate = .publishStateChange(connectivityState)
373380
}

Tests/GRPCNIOTransportCoreTests/Client/Connection/LoadBalancers/PickFirstLoadBalancerTests.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ final class PickFirstLoadBalancerTests: XCTestCase {
295295
case .connectivityStateChanged(.ready):
296296
switch idleCount.value {
297297
case 1:
298+
XCTAssertNotNil(context.loadBalancer.pickSubchannel())
298299
// Must be connected to server 1, send a GOAWAY frame.
299300
let channel = context.servers[0].server.clients.first!
300301
let goAway = HTTP2Frame(
@@ -307,6 +308,7 @@ final class PickFirstLoadBalancerTests: XCTestCase {
307308
// Must only be connected to server 2 now.
308309
XCTAssertEqual(context.servers[0].server.clients.count, 0)
309310
XCTAssertEqual(context.servers[1].server.clients.count, 1)
311+
XCTAssertNotNil(context.loadBalancer.pickSubchannel())
310312
context.loadBalancer.close()
311313

312314
default:

0 commit comments

Comments
 (0)