Skip to content

Commit a1c7ad3

Browse files
committed
update
1 parent 8750111 commit a1c7ad3

File tree

4 files changed

+191
-0
lines changed

4 files changed

+191
-0
lines changed
File renamed without changes.
File renamed without changes.

05-restore-sequence/_2/README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
Core :
2+
- 順序性: 步驟必須按順序執行
3+
- 可控制: 每個步驟都可以被控制和確認
4+
- 可恢復: 錯誤發生時可以從斷點恢復
5+
- 一致性: 確保數據和狀態的一致性
6+
7+
Use Case :
8+
- 需要嚴格順序控制的流程
9+
- 長時間運行的任務
10+
- 需要支援斷點續做的操作
11+
- 對數據一致性要求高的場景
12+
13+
14+
```mermaid
15+
sequenceDiagram
16+
participant M as Main
17+
participant G as Generator
18+
participant P as Processor
19+
20+
M->>G: generateSequence()
21+
activate G
22+
23+
loop Each Step
24+
G->>M: Send Step
25+
activate M
26+
27+
M->>P: processWithRetry(step, maxRetries)
28+
activate P
29+
30+
loop Retry Logic
31+
P->>P: processStep()
32+
alt Success
33+
P-->>M: return true
34+
else Error & Retries Left
35+
Note over P: Wait and Retry
36+
P->>P: retry++
37+
else Error & No Retries
38+
P-->>M: return false
39+
end
40+
end
41+
deactivate P
42+
43+
M->>G: step.waitFor <- success
44+
Note over G: Wait for signal
45+
G-->>M: Continue if received
46+
deactivate M
47+
end
48+
49+
G-->>M: Close channels
50+
deactivate G
51+
52+
Note over M: Print Results
53+
```

05-restore-sequence/_2/main.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"math/rand"
6+
"time"
7+
)
8+
9+
type Step struct {
10+
id int
11+
data interface{}
12+
waitFor chan bool
13+
}
14+
15+
type StepProcessor struct {
16+
lastSuccessful int
17+
results []string
18+
}
19+
20+
func generateSequence() (<-chan Step, <-chan error) {
21+
steps := make(chan Step)
22+
errors := make(chan error, 1)
23+
24+
testData := []string{
25+
"初始化系統",
26+
"載入配置",
27+
"連接數據庫",
28+
"啟動服務",
29+
"完成設定",
30+
}
31+
32+
go func() {
33+
defer close(steps)
34+
defer close(errors)
35+
36+
for i, data := range testData {
37+
// 為每個步驟創建等待channel
38+
waitForIt := make(chan bool)
39+
40+
step := Step{
41+
id: i + 1,
42+
data: data,
43+
waitFor: waitForIt,
44+
}
45+
46+
steps <- step
47+
48+
// 等待步驟確認或超時
49+
select {
50+
case <-waitForIt:
51+
fmt.Printf("步驟 %d 已確認完成\n", i+1)
52+
case <-time.After(5 * time.Second):
53+
errors <- fmt.Errorf("步驟 %d 等待超時", i+1)
54+
return
55+
}
56+
}
57+
}()
58+
59+
return steps, errors
60+
}
61+
62+
func (sp *StepProcessor) processStep(step Step) error {
63+
fmt.Printf("正在處理步驟 %d: %v\n", step.id, step.data)
64+
65+
time.Sleep(300 * time.Millisecond)
66+
67+
if rand.Float32() < 0.1 {
68+
return fmt.Errorf("處理步驟 %d 時發生錯誤", step.id)
69+
}
70+
71+
sp.lastSuccessful = step.id
72+
sp.results = append(sp.results, fmt.Sprintf("步驟 %d (%v) 處理完成", step.id, step.data))
73+
74+
return nil
75+
}
76+
77+
func (sp *StepProcessor) processWithRetry(step Step, maxRetries int) bool {
78+
for retry := 0; retry <= maxRetries; retry++ {
79+
if retry > 0 {
80+
fmt.Printf("重試步驟 %d (第 %d 次)\n", step.id, retry)
81+
time.Sleep(500 * time.Millisecond) // 重試前稍微等待
82+
}
83+
84+
err := sp.processStep(step)
85+
if err == nil {
86+
return true // 處理成功
87+
}
88+
89+
if retry < maxRetries {
90+
fmt.Printf("錯誤: %v (已重試 %d/%d)\n", err, retry, maxRetries)
91+
} else {
92+
fmt.Printf("步驟 %d 重試次數超過上限,放棄處理\n", step.id)
93+
}
94+
}
95+
return false // 所有重試都失敗
96+
}
97+
98+
func NewStepProcessor() *StepProcessor {
99+
return &StepProcessor{
100+
lastSuccessful: 0,
101+
results: make([]string, 0),
102+
}
103+
}
104+
105+
func main() {
106+
rand.Seed(time.Now().UnixNano())
107+
108+
processor := NewStepProcessor()
109+
steps, errors := generateSequence()
110+
maxRetries := 3
111+
112+
fmt.Println("開始處理序列...")
113+
fmt.Println("====================")
114+
115+
for {
116+
select {
117+
case step, ok := <-steps:
118+
if !ok {
119+
fmt.Println("====================")
120+
fmt.Println("序列處理完成!結果:")
121+
for _, result := range processor.results {
122+
fmt.Println(result)
123+
}
124+
return
125+
}
126+
127+
// 使用重試機制處理步驟
128+
success := processor.processWithRetry(step, maxRetries)
129+
130+
// 無論成功失敗,都要發送確認信號避免超時
131+
step.waitFor <- success
132+
133+
case err := <-errors:
134+
fmt.Printf("序列錯誤: %v\n", err)
135+
return
136+
}
137+
}
138+
}

0 commit comments

Comments
 (0)