-
Notifications
You must be signed in to change notification settings - Fork 159
Expand file tree
/
Copy pathpause.go
More file actions
102 lines (89 loc) · 2.88 KB
/
Copy pathpause.go
File metadata and controls
102 lines (89 loc) · 2.88 KB
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package main
import (
"context"
"encoding/json/v2"
"fmt"
"net/http"
"time"
"github.com/spf13/cobra"
"go.kenn.io/roborev/internal/storage"
)
type queuePauseResponse struct {
QueuePaused bool `json:"queue_paused"`
}
func pauseCmd() *cobra.Command {
return &cobra.Command{
Use: "pause",
Short: "Pause queue processing",
RunE: func(cmd *cobra.Command, args []string) error {
return setQueuePaused(true)
},
}
}
func unpauseCmd() *cobra.Command {
return &cobra.Command{
Use: "unpause",
Short: "Resume queue processing",
RunE: func(cmd *cobra.Command, args []string) error {
return setQueuePaused(false)
},
}
}
func setQueuePaused(paused bool) error {
// For a local daemon, carry the desired pause state into daemon startup so a
// cold-started or restarted daemon comes up with the flag already applied,
// before its workers can claim jobs. startDaemon persists it in the safe
// window after any previous daemon has stopped, so the CLI never migrates a
// live database. A healthy, current-version daemon is left running and picks
// up the state from the POST below instead.
if serverAddr == "" {
pendingStartPause = &paused
defer func() { pendingStartPause = nil }()
}
if err := ensureDaemon(); err != nil {
return err
}
ep := getDaemonEndpoint()
api := ep.APIClient(2 * time.Second)
update := api.UnpauseQueueRaw
if paused {
update = api.PauseQueueRaw
}
resp, err := update(context.Background())
if err != nil {
return fmt.Errorf("update queue pause state: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("update queue pause state: daemon returned %s", resp.Status)
}
var result queuePauseResponse
if err := json.UnmarshalRead(resp.Body, &result); err != nil {
return fmt.Errorf("parse queue pause response: %w", err)
}
if result.QueuePaused {
fmt.Println("Queue paused. Running jobs will continue; no new jobs will start.")
} else {
fmt.Println("Queue unpaused. Workers will start queued jobs again.")
}
return nil
}
// pendingStartPause carries the queue-pause state that startDaemon must persist
// to the local database immediately before launching a daemon. It lets a
// cold-started or restarted daemon come up with the pause flag already applied
// without the CLI opening the database while an older daemon still owns it.
var pendingStartPause *bool
// writeLocalQueuePaused persists the queue-pause flag to the default local
// database. The caller must ensure no daemon currently owns the database (for
// example, immediately before startDaemon launches a new one).
func writeLocalQueuePaused(paused bool) error {
db, err := storage.Open(storage.DefaultDBPath())
if err != nil {
return fmt.Errorf("open local daemon database: %w", err)
}
defer db.Close()
if err := db.SetQueuePaused(paused); err != nil {
return fmt.Errorf("persist local queue pause state: %w", err)
}
return nil
}