refactor(daemon): remove the test-only render ackReady gate
The render coordinator now probes output readiness only per attachment through ackReadyFor. Without attachment leases nothing gates output, which matches production where ackReady was never set.
- commit
- e15d552f697222749ef14384178ea60178105985
- author
- brice · · 2026-10-08 05:04 UTC
- parent
- 6fb053b
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
4 files · +32 -47
M internal/usecase/daemon/render_coordinator.go +10 -24
| @@ -991,9 +991,6 @@ func (c *renderCoordinator) attachmentAckReady(ac *attachedClient) bool { | |||
| 991 | 991 | if c.opts.ackReadyFor != nil { | |
| 992 | 992 | return c.opts.ackReadyFor(ac) | |
| 993 | 993 | } | |
| 994 | - | if c.opts.ackReady != nil { | |
| 995 | - | return c.opts.ackReady() | |
| 996 | - | } | |
| 997 | 994 | return true | |
| 998 | 995 | } | |
| 999 | 996 | ||
| @@ -1014,25 +1011,15 @@ func (c *renderCoordinator) fireWithTimerTokenAndLease(token *timerToken, gen ui | |||
| 1014 | 1011 | leases[ac] = lease | |
| 1015 | 1012 | } | |
| 1016 | 1013 | } | |
| 1017 | - | previewOnly := len(leases) == 0 && len(c.previewWakes) != 0 | |
| 1018 | - | legacyAckReady := c.opts.ackReady | |
| 1019 | 1014 | c.mu.Unlock() | |
| 1020 | 1015 | ||
| 1021 | 1016 | ready := make(map[*attachmentLease]bool, len(leases)) | |
| 1022 | - | if len(leases) != 0 { | |
| 1023 | - | for ac, lease := range leases { | |
| 1024 | - | // Welcome holds attachment.sendMu while its transport Send is in | |
| 1025 | - | // flight. Do not probe an incarnation before it is ready. | |
| 1026 | - | if lease.ready { | |
| 1027 | - | ready[lease] = c.attachmentAckReady(ac) | |
| 1028 | - | } | |
| 1017 | + | for ac, lease := range leases { | |
| 1018 | + | // Welcome holds attachment.sendMu while its transport Send is in | |
| 1019 | + | // flight. Do not probe an incarnation before it is ready. | |
| 1020 | + | if lease.ready { | |
| 1021 | + | ready[lease] = c.attachmentAckReady(ac) | |
| 1029 | 1022 | } | |
| 1030 | - | } else if !previewOnly && legacyAckReady != nil { | |
| 1031 | - | // Keep coordinator-only/headless callers compatible; production always | |
| 1032 | - | // has attachment leases and uses the per-attachment callback above. | |
| 1033 | - | ready[nil] = legacyAckReady() | |
| 1034 | - | } else { | |
| 1035 | - | ready[nil] = true | |
| 1036 | 1023 | } | |
| 1037 | 1024 | ||
| 1038 | 1025 | // The readiness callback can detach, replace, or publish a sync batch. | |
| @@ -1098,12 +1085,11 @@ func (c *renderCoordinator) fireWithTimerTokenAndLease(token *timerToken, gen ui | |||
| 1098 | 1085 | } | |
| 1099 | 1086 | c.ackDeferredFor[ac] = true | |
| 1100 | 1087 | } | |
| 1101 | - | } else if !ready[nil] { | |
| 1102 | - | blockedByAck = true | |
| 1103 | - | allDelivered = false | |
| 1104 | 1088 | } | |
| 1105 | - | legacyOutput := len(leases) == 0 && ready[nil] && (c.pendingShared || len(c.pendingTargets) == 0) | |
| 1106 | - | outputReady := len(attachmentLeases) != 0 || legacyOutput | |
| 1089 | + | // Without any attachment lease (headless sessions and coordinator-only | |
| 1090 | + | // callers) nothing gates output, so a shared invalidation renders directly. | |
| 1091 | + | leaselessOutput := len(leases) == 0 && (c.pendingShared || len(c.pendingTargets) == 0) | |
| 1092 | + | outputReady := len(attachmentLeases) != 0 || leaselessOutput | |
| 1107 | 1093 | if len(leases) != 0 { | |
| 1108 | 1094 | for ac, lease := range leases { | |
| 1109 | 1095 | if !c.pendingShared && len(c.pendingTargets) != 0 { | |
| @@ -1118,7 +1104,7 @@ func (c *renderCoordinator) fireWithTimerTokenAndLease(token *timerToken, gen ui | |||
| 1118 | 1104 | } | |
| 1119 | 1105 | } | |
| 1120 | 1106 | } | |
| 1121 | - | if len(leases) == 0 && legacyOutput { | |
| 1107 | + | if leaselessOutput { | |
| 1122 | 1108 | allDelivered = true | |
| 1123 | 1109 | } | |
| 1124 | 1110 | wakeGeneration := uint64(0) | |
| @@ -991,9 +991,6 @@ func (c *renderCoordinator) attachmentAckReady(ac *attachedClient) bool { | |||||
| 991 | if c.opts.ackReadyFor != nil { | 991 | if c.opts.ackReadyFor != nil { | ||
| 992 | return c.opts.ackReadyFor(ac) | 992 | return c.opts.ackReadyFor(ac) | ||
| 993 | } | 993 | } | ||
| 994 | - | if c.opts.ackReady != nil { | |||
| 995 | - | return c.opts.ackReady() | |||
| 996 | - | } | |||
| 997 | return true | 994 | return true | ||
| 998 | } | 995 | } | ||
| 999 | 996 | ||||
| @@ -1014,25 +1011,15 @@ func (c *renderCoordinator) fireWithTimerTokenAndLease(token *timerToken, gen ui | |||||
| 1014 | leases[ac] = lease | 1011 | leases[ac] = lease | ||
| 1015 | } | 1012 | } | ||
| 1016 | } | 1013 | } | ||
| 1017 | - | previewOnly := len(leases) == 0 && len(c.previewWakes) != 0 | |||
| 1018 | - | legacyAckReady := c.opts.ackReady | |||
| 1019 | c.mu.Unlock() | 1014 | c.mu.Unlock() | ||
| 1020 | 1015 | ||||
| 1021 | ready := make(map[*attachmentLease]bool, len(leases)) | 1016 | ready := make(map[*attachmentLease]bool, len(leases)) | ||
| 1022 | - | if len(leases) != 0 { | 1017 | + | for ac, lease := range leases { |
| 1023 | - | for ac, lease := range leases { | 1018 | + | // Welcome holds attachment.sendMu while its transport Send is in |
| 1024 | - | // Welcome holds attachment.sendMu while its transport Send is in | 1019 | + | // flight. Do not probe an incarnation before it is ready. |
| 1025 | - | // flight. Do not probe an incarnation before it is ready. | 1020 | + | if lease.ready { |
| 1026 | - | if lease.ready { | 1021 | + | ready[lease] = c.attachmentAckReady(ac) |
| 1027 | - | ready[lease] = c.attachmentAckReady(ac) | |||
| 1028 | - | } | |||
| 1029 | } | 1022 | } | ||
| 1030 | - | } else if !previewOnly && legacyAckReady != nil { | |||
| 1031 | - | // Keep coordinator-only/headless callers compatible; production always | |||
| 1032 | - | // has attachment leases and uses the per-attachment callback above. | |||
| 1033 | - | ready[nil] = legacyAckReady() | |||
| 1034 | - | } else { | |||
| 1035 | - | ready[nil] = true | |||
| 1036 | } | 1023 | } | ||
| 1037 | 1024 | ||||
| 1038 | // The readiness callback can detach, replace, or publish a sync batch. | 1025 | // The readiness callback can detach, replace, or publish a sync batch. | ||
| @@ -1098,12 +1085,11 @@ func (c *renderCoordinator) fireWithTimerTokenAndLease(token *timerToken, gen ui | |||||
| 1098 | } | 1085 | } | ||
| 1099 | c.ackDeferredFor[ac] = true | 1086 | c.ackDeferredFor[ac] = true | ||
| 1100 | } | 1087 | } | ||
| 1101 | - | } else if !ready[nil] { | |||
| 1102 | - | blockedByAck = true | |||
| 1103 | - | allDelivered = false | |||
| 1104 | } | 1088 | } | ||
| 1105 | - | legacyOutput := len(leases) == 0 && ready[nil] && (c.pendingShared || len(c.pendingTargets) == 0) | 1089 | + | // Without any attachment lease (headless sessions and coordinator-only |
| 1106 | - | outputReady := len(attachmentLeases) != 0 || legacyOutput | 1090 | + | // callers) nothing gates output, so a shared invalidation renders directly. |
| 1091 | + | leaselessOutput := len(leases) == 0 && (c.pendingShared || len(c.pendingTargets) == 0) | |||
| 1092 | + | outputReady := len(attachmentLeases) != 0 || leaselessOutput | |||
| 1107 | if len(leases) != 0 { | 1093 | if len(leases) != 0 { | ||
| 1108 | for ac, lease := range leases { | 1094 | for ac, lease := range leases { | ||
| 1109 | if !c.pendingShared && len(c.pendingTargets) != 0 { | 1095 | if !c.pendingShared && len(c.pendingTargets) != 0 { | ||
| @@ -1118,7 +1104,7 @@ func (c *renderCoordinator) fireWithTimerTokenAndLease(token *timerToken, gen ui | |||||
| 1118 | } | 1104 | } | ||
| 1119 | } | 1105 | } | ||
| 1120 | } | 1106 | } | ||
| 1121 | - | if len(leases) == 0 && legacyOutput { | 1107 | + | if leaselessOutput { |
| 1122 | allDelivered = true | 1108 | allDelivered = true | ||
| 1123 | } | 1109 | } | ||
| 1124 | wakeGeneration := uint64(0) | 1110 | wakeGeneration := uint64(0) | ||
M internal/usecase/daemon/render_coordinator_test.go +9 -9
| @@ -97,7 +97,7 @@ func TestRenderCoordinatorDetachDoesNotJoinSelectedDeadlineWorker(t *testing.T) | |||
| 97 | 97 | release := make(chan struct{}) | |
| 98 | 98 | rc := newRenderCoordinator(renderCoordinatorOptions{ | |
| 99 | 99 | clock: clock, | |
| 100 | - | ackReady: func() bool { | |
| 100 | + | ackReadyFor: func(*attachedClient) bool { | |
| 101 | 101 | close(entered) | |
| 102 | 102 | <-release | |
| 103 | 103 | return true | |
| @@ -166,10 +166,10 @@ func newCoordinatorHarness(t *testing.T) *coordinatorHarness { | |||
| 166 | 166 | } | |
| 167 | 167 | h.ackReady.Store(true) | |
| 168 | 168 | h.rc = newRenderCoordinator(renderCoordinatorOptions{ | |
| 169 | - | clock: h.clk.clock, | |
| 170 | - | wake: func(w renderWake) { h.wakes <- w }, | |
| 171 | - | ackReady: func() bool { return h.ackReady.Load() }, | |
| 172 | - | syncActive: func() bool { return h.syncActive.Load() }, | |
| 169 | + | clock: h.clk.clock, | |
| 170 | + | wake: func(w renderWake) { h.wakes <- w }, | |
| 171 | + | ackReadyFor: func(*attachedClient) bool { return h.ackReady.Load() }, | |
| 172 | + | syncActive: func() bool { return h.syncActive.Load() }, | |
| 173 | 173 | }) | |
| 174 | 174 | return h | |
| 175 | 175 | } | |
| @@ -449,7 +449,7 @@ func TestRenderCoordinatorAckReadinessReentersWithoutBlockingResize(t *testing.T | |||
| 449 | 449 | ||
| 450 | 450 | var rc *renderCoordinator | |
| 451 | 451 | rc = newRenderCoordinator(renderCoordinatorOptions{ | |
| 452 | - | ackReady: func() bool { | |
| 452 | + | ackReadyFor: func(*attachedClient) bool { | |
| 453 | 453 | close(ackEntered) | |
| 454 | 454 | // The readiness probe models the output send path reading coordinator | |
| 455 | 455 | // metadata after sendMu is held. It must never run under c.mu. | |
| @@ -1451,9 +1451,9 @@ func TestRenderCoordinatorInertTimerFiresSynchronouslyWithoutWorker(t *testing.T | |||
| 1451 | 1451 | ||
| 1452 | 1452 | wakes := make(chan renderWake, 1) | |
| 1453 | 1453 | rc := newRenderCoordinator(renderCoordinatorOptions{ | |
| 1454 | - | clock: clock, | |
| 1455 | - | ackReady: func() bool { return true }, | |
| 1456 | - | wake: func(w renderWake) { wakes <- w }, | |
| 1454 | + | clock: clock, | |
| 1455 | + | ackReadyFor: func(*attachedClient) bool { return true }, | |
| 1456 | + | wake: func(w renderWake) { wakes <- w }, | |
| 1457 | 1457 | }) | |
| 1458 | 1458 | rc.invalidate(renderInvalidation{class: invalidateOutput}) | |
| 1459 | 1459 | ||
| @@ -97,7 +97,7 @@ func TestRenderCoordinatorDetachDoesNotJoinSelectedDeadlineWorker(t *testing.T) | |||||
| 97 | release := make(chan struct{}) | 97 | release := make(chan struct{}) | ||
| 98 | rc := newRenderCoordinator(renderCoordinatorOptions{ | 98 | rc := newRenderCoordinator(renderCoordinatorOptions{ | ||
| 99 | clock: clock, | 99 | clock: clock, | ||
| 100 | - | ackReady: func() bool { | 100 | + | ackReadyFor: func(*attachedClient) bool { |
| 101 | close(entered) | 101 | close(entered) | ||
| 102 | <-release | 102 | <-release | ||
| 103 | return true | 103 | return true | ||
| @@ -166,10 +166,10 @@ func newCoordinatorHarness(t *testing.T) *coordinatorHarness { | |||||
| 166 | } | 166 | } | ||
| 167 | h.ackReady.Store(true) | 167 | h.ackReady.Store(true) | ||
| 168 | h.rc = newRenderCoordinator(renderCoordinatorOptions{ | 168 | h.rc = newRenderCoordinator(renderCoordinatorOptions{ | ||
| 169 | - | clock: h.clk.clock, | 169 | + | clock: h.clk.clock, |
| 170 | - | wake: func(w renderWake) { h.wakes <- w }, | 170 | + | wake: func(w renderWake) { h.wakes <- w }, |
| 171 | - | ackReady: func() bool { return h.ackReady.Load() }, | 171 | + | ackReadyFor: func(*attachedClient) bool { return h.ackReady.Load() }, |
| 172 | - | syncActive: func() bool { return h.syncActive.Load() }, | 172 | + | syncActive: func() bool { return h.syncActive.Load() }, |
| 173 | }) | 173 | }) | ||
| 174 | return h | 174 | return h | ||
| 175 | } | 175 | } | ||
| @@ -449,7 +449,7 @@ func TestRenderCoordinatorAckReadinessReentersWithoutBlockingResize(t *testing.T | |||||
| 449 | 449 | ||||
| 450 | var rc *renderCoordinator | 450 | var rc *renderCoordinator | ||
| 451 | rc = newRenderCoordinator(renderCoordinatorOptions{ | 451 | rc = newRenderCoordinator(renderCoordinatorOptions{ | ||
| 452 | - | ackReady: func() bool { | 452 | + | ackReadyFor: func(*attachedClient) bool { |
| 453 | close(ackEntered) | 453 | close(ackEntered) | ||
| 454 | // The readiness probe models the output send path reading coordinator | 454 | // The readiness probe models the output send path reading coordinator | ||
| 455 | // metadata after sendMu is held. It must never run under c.mu. | 455 | // metadata after sendMu is held. It must never run under c.mu. | ||
| @@ -1451,9 +1451,9 @@ func TestRenderCoordinatorInertTimerFiresSynchronouslyWithoutWorker(t *testing.T | |||||
| 1451 | 1451 | ||||
| 1452 | wakes := make(chan renderWake, 1) | 1452 | wakes := make(chan renderWake, 1) | ||
| 1453 | rc := newRenderCoordinator(renderCoordinatorOptions{ | 1453 | rc := newRenderCoordinator(renderCoordinatorOptions{ | ||
| 1454 | - | clock: clock, | 1454 | + | clock: clock, |
| 1455 | - | ackReady: func() bool { return true }, | 1455 | + | ackReadyFor: func(*attachedClient) bool { return true }, |
| 1456 | - | wake: func(w renderWake) { wakes <- w }, | 1456 | + | wake: func(w renderWake) { wakes <- w }, |
| 1457 | }) | 1457 | }) | ||
| 1458 | rc.invalidate(renderInvalidation{class: invalidateOutput}) | 1458 | rc.invalidate(renderInvalidation{class: invalidateOutput}) | ||
| 1459 | 1459 | ||||
M internal/usecase/daemon/render_coordinator_types.go +3 -5
| @@ -105,11 +105,9 @@ type renderCoordinatorOptions struct { | |||
| 105 | 105 | observer ports.RuntimeObserver | |
| 106 | 106 | // wake composes a coalesced render request. | |
| 107 | 107 | wake func(renderWake) | |
| 108 | - | // ackReady reports whether the attachment may compose another output | |
| 109 | - | // state (the attachmentOutput window has capacity). It is retained for | |
| 110 | - | // coordinator-only tests and headless callers; production uses ackReadyFor | |
| 111 | - | // so one attachment cannot gate another. | |
| 112 | - | ackReady func() bool | |
| 108 | + | // ackReadyFor reports whether one attachment may compose another output | |
| 109 | + | // state (its attachmentOutput window has capacity), so one attachment | |
| 110 | + | // cannot gate another. Nil means every attachment is ready. | |
| 113 | 111 | ackReadyFor func(*attachedClient) bool | |
| 114 | 112 | // syncRenderable reports whether a pane's synchronized batch currently | |
| 115 | 113 | // contributes to the attached composition. It must not acquire c.mu. | |
| @@ -105,11 +105,9 @@ type renderCoordinatorOptions struct { | |||||
| 105 | observer ports.RuntimeObserver | 105 | observer ports.RuntimeObserver | ||
| 106 | // wake composes a coalesced render request. | 106 | // wake composes a coalesced render request. | ||
| 107 | wake func(renderWake) | 107 | wake func(renderWake) | ||
| 108 | - | // ackReady reports whether the attachment may compose another output | 108 | + | // ackReadyFor reports whether one attachment may compose another output |
| 109 | - | // state (the attachmentOutput window has capacity). It is retained for | 109 | + | // state (its attachmentOutput window has capacity), so one attachment |
| 110 | - | // coordinator-only tests and headless callers; production uses ackReadyFor | 110 | + | // cannot gate another. Nil means every attachment is ready. |
| 111 | - | // so one attachment cannot gate another. | |||
| 112 | - | ackReady func() bool | |||
| 113 | ackReadyFor func(*attachedClient) bool | 111 | ackReadyFor func(*attachedClient) bool | ||
| 114 | // syncRenderable reports whether a pane's synchronized batch currently | 112 | // syncRenderable reports whether a pane's synchronized batch currently | ||
| 115 | // contributes to the attached composition. It must not acquire c.mu. | 113 | // contributes to the attached composition. It must not acquire c.mu. | ||
M internal/usecase/daemon/transport_observability_test.go +10 -9
| @@ -188,8 +188,8 @@ func TestTransportObservabilityACKBlockedSpansEndExactlyOnce(t *testing.T) { | |||
| 188 | 188 | observer := &daemonRuntimeObserver{} | |
| 189 | 189 | ready := false | |
| 190 | 190 | rc := newRenderCoordinator(renderCoordinatorOptions{ | |
| 191 | - | observer: observer, | |
| 192 | - | ackReady: func() bool { return ready }, | |
| 191 | + | observer: observer, | |
| 192 | + | ackReadyFor: func(*attachedClient) bool { return ready }, | |
| 193 | 193 | }) | |
| 194 | 194 | rc.attach(&attachedClient{}) | |
| 195 | 195 | rc.invalidate(renderInvalidation{class: invalidateOutput}) | |
| @@ -233,9 +233,9 @@ func TestTransportObservabilityBlockedACKEndDoesNotDelayNotifyAck(t *testing.T) | |||
| 233 | 233 | wakes := make(chan renderWake, 1) | |
| 234 | 234 | var ready atomic.Bool | |
| 235 | 235 | rc := newRenderCoordinator(renderCoordinatorOptions{ | |
| 236 | - | observer: d.runtimeObserver, | |
| 237 | - | ackReady: ready.Load, | |
| 238 | - | wake: func(w renderWake) { wakes <- w }, | |
| 236 | + | observer: d.runtimeObserver, | |
| 237 | + | ackReadyFor: func(*attachedClient) bool { return ready.Load() }, | |
| 238 | + | wake: func(w renderWake) { wakes <- w }, | |
| 239 | 239 | }) | |
| 240 | 240 | rc.attach(&attachedClient{}) | |
| 241 | 241 | rc.invalidate(renderInvalidation{class: invalidateOutput}) | |
| @@ -284,8 +284,8 @@ func (o *blockingACKEndObserver) ObserveRuntime(mark ports.RuntimeMark) { | |||
| 284 | 284 | func TestTransportObservabilityBlockedCoordinatorObserverReleasesLock(t *testing.T) { | |
| 285 | 285 | observer := newBlockingDaemonRuntimeObserver() | |
| 286 | 286 | rc := newRenderCoordinator(renderCoordinatorOptions{ | |
| 287 | - | observer: observer, | |
| 288 | - | ackReady: func() bool { return false }, | |
| 287 | + | observer: observer, | |
| 288 | + | ackReadyFor: func(*attachedClient) bool { return false }, | |
| 289 | 289 | }) | |
| 290 | 290 | rc.attach(&attachedClient{}) | |
| 291 | 291 | rc.mu.Lock() | |
| @@ -347,9 +347,10 @@ func TestTransportObservabilityACKBlockedStartPublishesBeforeEnd(t *testing.T) { | |||
| 347 | 347 | observer := newACKSpanInterleavingObserver() | |
| 348 | 348 | ready := false | |
| 349 | 349 | rc := newRenderCoordinator(renderCoordinatorOptions{ | |
| 350 | - | observer: observer, | |
| 351 | - | ackReady: func() bool { return ready }, | |
| 350 | + | observer: observer, | |
| 351 | + | ackReadyFor: func(*attachedClient) bool { return ready }, | |
| 352 | 352 | }) | |
| 353 | + | rc.attach(&attachedClient{}) | |
| 353 | 354 | rc.mu.Lock() | |
| 354 | 355 | rc.pending = true | |
| 355 | 356 | gen := rc.normalLane.generation | |
| @@ -188,8 +188,8 @@ func TestTransportObservabilityACKBlockedSpansEndExactlyOnce(t *testing.T) { | |||||
| 188 | observer := &daemonRuntimeObserver{} | 188 | observer := &daemonRuntimeObserver{} | ||
| 189 | ready := false | 189 | ready := false | ||
| 190 | rc := newRenderCoordinator(renderCoordinatorOptions{ | 190 | rc := newRenderCoordinator(renderCoordinatorOptions{ | ||
| 191 | - | observer: observer, | 191 | + | observer: observer, |
| 192 | - | ackReady: func() bool { return ready }, | 192 | + | ackReadyFor: func(*attachedClient) bool { return ready }, |
| 193 | }) | 193 | }) | ||
| 194 | rc.attach(&attachedClient{}) | 194 | rc.attach(&attachedClient{}) | ||
| 195 | rc.invalidate(renderInvalidation{class: invalidateOutput}) | 195 | rc.invalidate(renderInvalidation{class: invalidateOutput}) | ||
| @@ -233,9 +233,9 @@ func TestTransportObservabilityBlockedACKEndDoesNotDelayNotifyAck(t *testing.T) | |||||
| 233 | wakes := make(chan renderWake, 1) | 233 | wakes := make(chan renderWake, 1) | ||
| 234 | var ready atomic.Bool | 234 | var ready atomic.Bool | ||
| 235 | rc := newRenderCoordinator(renderCoordinatorOptions{ | 235 | rc := newRenderCoordinator(renderCoordinatorOptions{ | ||
| 236 | - | observer: d.runtimeObserver, | 236 | + | observer: d.runtimeObserver, |
| 237 | - | ackReady: ready.Load, | 237 | + | ackReadyFor: func(*attachedClient) bool { return ready.Load() }, |
| 238 | - | wake: func(w renderWake) { wakes <- w }, | 238 | + | wake: func(w renderWake) { wakes <- w }, |
| 239 | }) | 239 | }) | ||
| 240 | rc.attach(&attachedClient{}) | 240 | rc.attach(&attachedClient{}) | ||
| 241 | rc.invalidate(renderInvalidation{class: invalidateOutput}) | 241 | rc.invalidate(renderInvalidation{class: invalidateOutput}) | ||
| @@ -284,8 +284,8 @@ func (o *blockingACKEndObserver) ObserveRuntime(mark ports.RuntimeMark) { | |||||
| 284 | func TestTransportObservabilityBlockedCoordinatorObserverReleasesLock(t *testing.T) { | 284 | func TestTransportObservabilityBlockedCoordinatorObserverReleasesLock(t *testing.T) { | ||
| 285 | observer := newBlockingDaemonRuntimeObserver() | 285 | observer := newBlockingDaemonRuntimeObserver() | ||
| 286 | rc := newRenderCoordinator(renderCoordinatorOptions{ | 286 | rc := newRenderCoordinator(renderCoordinatorOptions{ | ||
| 287 | - | observer: observer, | 287 | + | observer: observer, |
| 288 | - | ackReady: func() bool { return false }, | 288 | + | ackReadyFor: func(*attachedClient) bool { return false }, |
| 289 | }) | 289 | }) | ||
| 290 | rc.attach(&attachedClient{}) | 290 | rc.attach(&attachedClient{}) | ||
| 291 | rc.mu.Lock() | 291 | rc.mu.Lock() | ||
| @@ -347,9 +347,10 @@ func TestTransportObservabilityACKBlockedStartPublishesBeforeEnd(t *testing.T) { | |||||
| 347 | observer := newACKSpanInterleavingObserver() | 347 | observer := newACKSpanInterleavingObserver() | ||
| 348 | ready := false | 348 | ready := false | ||
| 349 | rc := newRenderCoordinator(renderCoordinatorOptions{ | 349 | rc := newRenderCoordinator(renderCoordinatorOptions{ | ||
| 350 | - | observer: observer, | 350 | + | observer: observer, |
| 351 | - | ackReady: func() bool { return ready }, | 351 | + | ackReadyFor: func(*attachedClient) bool { return ready }, |
| 352 | }) | 352 | }) | ||
| 353 | + | rc.attach(&attachedClient{}) | |||
| 353 | rc.mu.Lock() | 354 | rc.mu.Lock() | ||
| 354 | rc.pending = true | 355 | rc.pending = true | ||
| 355 | gen := rc.normalLane.generation | 356 | gen := rc.normalLane.generation | ||