detached a710b51

fix(daemon): publish deadline before invalidation hook

commit
a710b5136fa24f0b8e17cb9f39d183ef72fc8c0a
author
brice · · 2026-07-11 20:03 UTC
parent
5c0dde8
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +15 -3
M internal/usecase/daemon/render_coordinator.go +15 -3
@@ -276,10 +276,10 @@ func (c *renderCoordinator) invalidateForAttachment(source *attachedClient, inv
276276 c.armed = c.armed || arm
277277 c.mu.Unlock()
278278 stopTimer(old)
279- if onInvalidate != nil {
280- onInvalidate(inv)
281- }
282279 if !arm || clock == nil {
280+ if onInvalidate != nil {
281+ onInvalidate(inv)
282+ }
283283 return
284284 }
285285
@@ -297,11 +297,17 @@ func (c *renderCoordinator) invalidateForAttachment(source *attachedClient, inv
297297 c.mu.Unlock()
298298 if !valid {
299299 stopTimer(timer)
300+ if onInvalidate != nil {
301+ onInvalidate(inv)
302+ }
300303 return
301304 }
302305 if timerC == nil {
303306 stopTimer(timer)
304307 c.fire(gen, false, true)
308+ if onInvalidate != nil {
309+ onInvalidate(inv)
310+ }
305311 return
306312 }
307313 go func() {
@@ -313,6 +319,12 @@ func (c *renderCoordinator) invalidateForAttachment(source *attachedClient, inv
313319 case <-cancel:
314320 }
315321 }()
322+ // Test-visible observation follows deadline publication, so a producer
323+ // callback cannot observe a successful invalidation before its timer owns
324+ // a worker (and race tests cannot finish while a mock expectation remains).
325+ if onInvalidate != nil {
326+ onInvalidate(inv)
327+ }
316328 runtime.Gosched()
317329 }
318330
@@ -276,10 +276,10 @@ func (c *renderCoordinator) invalidateForAttachment(source *attachedClient, inv
276 c.armed = c.armed || arm276 c.armed = c.armed || arm
277 c.mu.Unlock()277 c.mu.Unlock()
278 stopTimer(old)278 stopTimer(old)
279- if onInvalidate != nil {
280- onInvalidate(inv)
281- }
282 if !arm || clock == nil {279 if !arm || clock == nil {
280+ if onInvalidate != nil {
281+ onInvalidate(inv)
282+ }
283 return283 return
284 }284 }
285 285
@@ -297,11 +297,17 @@ func (c *renderCoordinator) invalidateForAttachment(source *attachedClient, inv
297 c.mu.Unlock()297 c.mu.Unlock()
298 if !valid {298 if !valid {
299 stopTimer(timer)299 stopTimer(timer)
300+ if onInvalidate != nil {
301+ onInvalidate(inv)
302+ }
300 return303 return
301 }304 }
302 if timerC == nil {305 if timerC == nil {
303 stopTimer(timer)306 stopTimer(timer)
304 c.fire(gen, false, true)307 c.fire(gen, false, true)
308+ if onInvalidate != nil {
309+ onInvalidate(inv)
310+ }
305 return311 return
306 }312 }
307 go func() {313 go func() {
@@ -313,6 +319,12 @@ func (c *renderCoordinator) invalidateForAttachment(source *attachedClient, inv
313 case <-cancel:319 case <-cancel:
314 }320 }
315 }()321 }()
322+ // Test-visible observation follows deadline publication, so a producer
323+ // callback cannot observe a successful invalidation before its timer owns
324+ // a worker (and race tests cannot finish while a mock expectation remains).
325+ if onInvalidate != nil {
326+ onInvalidate(inv)
327+ }
316 runtime.Gosched()328 runtime.Gosched()
317 }329 }
318 330

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close