返回 DeepSeek-Reasonix
session_destroy_wait.go
根目录 / desktop / session_destroy_wait.go
1 package main
2
3 import (
4 "time"
5
6 "reasonix/internal/control"
7 "reasonix/internal/jobs"
8 )
9
10 // Interactive removal returns promptly; durable cleanup-pending markers let
11 // delayed cleanup safely own non-cooperative jobs after this grace expires.
12 const desktopSessionRemovalGrace = time.Second
13 const desktopSessionRemovalWatchdog = desktopSessionRemovalGrace + 250*time.Millisecond
14
15 func waitDestroyHandles(destroys []control.SessionDestroyHandle) bool {
16 return waitDestroyHandleBatches([][]control.SessionDestroyHandle{destroys})[0]
17 }
18
19 func waitDestroyHandleBatches(batches [][]control.SessionDestroyHandle) []bool {
20 timedOut := make([]bool, len(batches))
21 if len(batches) == 0 {
22 return timedOut
23 }
24 type batchResult struct {
25 index int
26 timedOut bool
27 }
28 deadline := time.Now().Add(desktopSessionRemovalWatchdog)
29 results := make(chan batchResult, len(batches))
30 for i, destroys := range batches {
31 go func() {
32 results <- batchResult{index: i, timedOut: waitDestroyHandlesUntil(destroys, deadline)}
33 }()
34 }
35 for range batches {
36 result := <-results
37 timedOut[result.index] = result.timedOut
38 }
39 return timedOut
40 }
41
42 func waitDestroyHandlesUntil(destroys []control.SessionDestroyHandle, deadline time.Time) bool {
43 results := make(chan jobs.TeardownResult, len(destroys))
44 waits := 0
45 for _, destroy := range destroys {
46 wait := destroy.Wait
47 if destroy.WaitFor != nil {
48 remaining := min(max(time.Until(deadline), time.Duration(0)), desktopSessionRemovalGrace)
49 wait = func() jobs.TeardownResult { return destroy.WaitFor(remaining) }
50 }
51 if wait == nil {
52 continue
53 }
54 waits++
55 go func(wait func() jobs.TeardownResult) { results <- wait() }(wait)
56 }
57 if waits == 0 {
58 return false
59 }
60 remaining := time.Until(deadline)
61 if remaining <= 0 {
62 return true
63 }
64 timer := time.NewTimer(remaining)
65 defer timer.Stop()
66 timedOut := false
67 for range waits {
68 select {
69 case result := <-results:
70 timedOut = timedOut || result.HasTimedOut()
71 case <-timer.C:
72 return true
73 }
74 }
75 return timedOut
76 }
77
77 lines GO