dashboard / erock/pico / fix(pipe): use ticker timer instead of sleep #100 rss

open · opened on 2025-12-26T04:53:44Z by erock
Help
checkout latest patchset:
ssh pr.pico.sh print pr-100 | git am -3
checkout any patchset in a patch request:
ssh pr.pico.sh print ps-X | git am -3
add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add 100
add review to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add --review 100
accept PR:
ssh pr.pico.sh pr accept 100
close PR:
ssh pr.pico.sh pr close 100

Logs

erock created pr with ps-183 on 2025-12-26T04:53:44Z

Patchsets

ps-183 by erock on 2025-12-26T04:53:44Z

Patchset ps-183

fix(pipe): use ticker timer instead of sleep

Eric Bower
2025-12-26T04:45:05Z
Back to top
The time.Sleep in the default case blocks for 5 seconds, during which context cancellation is ignored.
If the session ends, the goroutine won't notice until the sleep completes.
+19 -19 pkg/apps/pipe/cli.go link
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
diff --git a/pkg/apps/pipe/cli.go b/pkg/apps/pipe/cli.go
index 75b4f9a..fd3acce 100644
--- a/pkg/apps/pipe/cli.go
+++ b/pkg/apps/pipe/cli.go
@@ -52,25 +52,6 @@ func Middleware(handler *CliHandler) pssh.SSHServerMiddleware {
 
 			pipeCtx, cancel := context.WithCancel(ctx)
 
-			go func() {
-				defer cancel()
-
-				for {
-					select {
-					case <-pipeCtx.Done():
-						return
-					default:
-						_, err := sesh.SendRequest("ping@pico.sh", false, nil)
-						if err != nil {
-							logger.Error("error sending ping", "err", err)
-							return
-						}
-
-						time.Sleep(5 * time.Second)
-					}
-				}
-			}()
-
 			cliCmd := &CliCmd{
 				sesh:     sesh,
 				args:     args,
@@ -118,6 +99,25 @@ func Middleware(handler *CliHandler) pssh.SSHServerMiddleware {
 				sesh.RemoteAddr().String(),
 			)
 
+			defer cancel()
+			go func() {
+				ticker := time.NewTicker(5 * time.Second)
+				defer ticker.Stop()
+
+				for {
+					select {
+					case <-pipeCtx.Done():
+						return
+					case <-ticker.C:
+						_, err := sesh.SendRequest("ping@pico.sh", false, nil)
+						if err != nil {
+							logger.Error("error sending ping", "err", err)
+							return
+						}
+					}
+				}
+			}()
+
 			switch cmd {
 			case "pub":
 				err := handler.pub(cliCmd, topic, clientID)