Repository navigation
Expand file tree
/
Copy pathtimeoutcontroller.go
More file actions
132 lines (110 loc) · 3.58 KB
/
Copy pathtimeoutcontroller.go
File metadata and controls
132 lines (110 loc) · 3.58 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package pyExecuter
import (
"context"
"fmt"
"sync"
"time"
)
// TimeoutController 任务超时控制结构体
type TimeoutController struct {
taskTimeouts map[string]time.Time // 保存任务的截止时间
taskCancellations map[string]context.CancelFunc // 保存任务的取消函数
mu sync.RWMutex
}
// TimeoutControl 任务超时控制接口
type TimeoutControl interface {
SetTaskTimeout(taskID string, duration time.Duration) error // 设置任务的超时时间
CheckTimeout(taskID string) (bool, error) // 检查任务是否已超时
HandleTimeout(taskID string) error // 处理超时任务
ClearTimeout(taskID string) error // 清理任务的超时设置
}
// NewTimeoutController 创建 TimeoutController 实例
func NewTimeoutController() *TimeoutController {
return &TimeoutController{
taskTimeouts: make(map[string]time.Time),
taskCancellations: make(map[string]context.CancelFunc),
}
}
// SetTaskTimeout 设置任务的超时时间
func (t *TimeoutController) SetTaskTimeout(taskID string, duration time.Duration) error {
t.mu.Lock()
defer t.mu.Unlock()
deadline := time.Now().Add(duration)
t.taskTimeouts[taskID] = deadline
ctx, cancel := context.WithDeadline(context.Background(), deadline)
t.taskCancellations[taskID] = cancel
go func() {
<-ctx.Done()
if ctx.Err() == context.DeadlineExceeded {
t.HandleTimeout(taskID)
}
}()
fmt.Printf("Task %s timeout set to %s\n", taskID, duration)
return nil
}
// CheckTimeout 检查任务是否已经超时
func (t *TimeoutController) CheckTimeout(taskID string) (bool, error) {
t.mu.RLock()
defer t.mu.RUnlock()
deadline, exists := t.taskTimeouts[taskID]
if !exists {
return false, fmt.Errorf("no timeout set for task %s", taskID)
}
if time.Now().After(deadline) {
fmt.Printf("Task %s has timed out\n", taskID)
return true, nil
}
return false, nil
}
// HandleTimeout 处理超时任务
func (t *TimeoutController) HandleTimeout(taskID string) error {
t.mu.Lock()
defer t.mu.Unlock()
cancel, exists := t.taskCancellations[taskID]
if !exists {
return fmt.Errorf("no cancellation function for task %s", taskID)
}
cancel() // 取消任务
delete(t.taskTimeouts, taskID)
delete(t.taskCancellations, taskID)
fmt.Printf("Handling timeout for task %s: terminating task\n", taskID)
return nil
}
// ClearTimeout 清理任务的超时设置
func (t *TimeoutController) ClearTimeout(taskID string) error {
t.mu.Lock()
defer t.mu.Unlock()
cancel, exists := t.taskCancellations[taskID]
if !exists {
return fmt.Errorf("no timeout set for task %s", taskID)
}
cancel() // 取消定时器
delete(t.taskTimeouts, taskID)
delete(t.taskCancellations, taskID)
fmt.Printf("Cleared timeout for task %s\n", taskID)
return nil
}
// ExecuteWithTimeoutControl 演示如何使用 TimeoutControl
func ExecuteWithTimeoutControl(ctx context.Context, task *Task, timeoutControl TimeoutControl) error {
err := timeoutControl.SetTaskTimeout(task.ID, task.Timeout)
if err != nil {
return fmt.Errorf("failed to set timeout: %v", err)
}
defer timeoutControl.ClearTimeout(task.ID)
// 模拟任务执行
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(task.Timeout / 2): // 假设任务在超时之前完成
// 任务完成,检查是否已超时
timedOut, err := timeoutControl.CheckTimeout(task.ID)
if err != nil {
return fmt.Errorf("failed to check timeout: %v", err)
}
if timedOut {
return fmt.Errorf("task %s timed out", task.ID)
}
fmt.Printf("Task %s completed successfully\n", task.ID)
return nil
}
}