Skip to content

Commit 61e07a2

Browse files
committed
update README
1 parent 3c0e541 commit 61e07a2

File tree

2 files changed

+96
-4
lines changed

2 files changed

+96
-4
lines changed

README.md

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,52 @@ keeper := shutdownKeeper.NewKeeper(shutdownKeeper.KeeperOpts{
200200
})
201201
```
202202

203+
### Chained HoldToken
204+
The chained HoldToken feature allows you to create hierarchical HoldToken structures with dependencies. Child tokens will wait for parent tokens to be released before executing their shutdown logic. This mechanism ensures the orderly shutdown of multiple dependent modules in complex scenarios.
205+
206+
```go
207+
package main
208+
209+
import (
210+
"context"
211+
"fmt"
212+
"time"
213+
"os"
214+
"syscall"
215+
216+
"github.com/hsldymq/shutdownKeeper/v2"
217+
)
218+
219+
func main() {
220+
keeper := shutdownKeeper.NewKeeper(shutdownKeeper.KeeperOpts{
221+
Signals: []os.Signal{syscall.SIGINT, syscall.SIGTERM},
222+
})
223+
224+
// Create tokens for two modules, where module A should be released before module B
225+
moduleAToken := keeper.AllocHoldToken()
226+
moduleBToken := moduleAToken.AllocChainedToken()
227+
228+
// Module A shutdown logic
229+
moduleAToken.DoOnShutdown(func(ctx context.Context) {
230+
fmt.Printf("Module A starting shutdown...")
231+
// Simulate some cleanup work
232+
time.Sleep(2 * time.Second)
233+
fmt.Println("Module A shutdown completed")
234+
})
235+
236+
// Module B shutdown logic (will wait for module A to shutdown first)
237+
moduleBToken.DoOnShutdown(func(ctx context.Context) {
238+
fmt.Printf("Module B starting shutdown...")
239+
time.Sleep(1 * time.Second)
240+
fmt.Println("Module B shutdown completed")
241+
})
242+
243+
fmt.Println("Application started, press Ctrl+C to test ordered shutdown")
244+
keeper.Wait()
245+
fmt.Println("Application gracefully shut down in order")
246+
}
247+
```
248+
203249
## Frequently Asked Questions
204250

205251
### Q: Why not use context.WithCancel directly?
@@ -210,6 +256,6 @@ A: Context can only pass cancellation signals but cannot ensure that all gorouti
210256

211257
A: Set the `MaxHoldTime` parameter, and it will force exit after timeout. You can also set your own timeout logic within each module.
212258

213-
### Q: Can Tokens be dynamically allocated at runtime?
259+
### Q: Can HoldTokens be dynamically allocated at runtime?
214260

215261
A: Yes! You can call `AllocHoldToken()` at any time, and Keeper will track all allocated tokens.

README_CN.md

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
---
88

9-
这个库用于帮助你实现程序的优雅退出它提供一个协调管理器使程序和各个子模块之间在关闭过程中能够双向同步状态
9+
这个库用于帮助你实现程序的优雅退出. 它提供一个协调管理器, 使程序和各个子模块之间在关闭过程中能够双向同步状态.
1010

11-
各个模块可以感知到程序的关闭信号从而进行收尾工作模块也能够通知协调管理器自己已经完成了收尾工作这样既能最大限度避免数据丢失和不一致也不必过度等待太长时间
11+
各个模块可以感知到程序的关闭信号, 从而进行收尾工作. 模块也能够通知协调管理器自己已经完成了收尾工作. 这样既能最大限度避免数据丢失和不一致, 也不必过度等待太长时间.
1212

1313
### 安装
1414

@@ -200,6 +200,52 @@ keeper := shutdownKeeper.NewKeeper(shutdownKeeper.KeeperOpts{
200200
})
201201
```
202202

203+
### 链式 HoldToken
204+
链式HoldToken功能允许你创建具有依赖关系的 HoldToken 层级结构.子Token 会等待父Token 释放后才开始执行其关闭逻辑. 这种机制用于在一些复杂场景下确保多个有依赖关系模块的关闭操作的顺序性.
205+
206+
```go
207+
package main
208+
209+
import (
210+
"context"
211+
"fmt"
212+
"time"
213+
"os"
214+
"syscall"
215+
216+
"github.com/hsldymq/shutdownKeeper/v2"
217+
)
218+
219+
func main() {
220+
keeper := shutdownKeeper.NewKeeper(shutdownKeeper.KeeperOpts{
221+
Signals: []os.Signal{syscall.SIGINT, syscall.SIGTERM},
222+
})
223+
224+
// 分别创建两个模块的 Token, 其中模块A的释放应该先于模块B
225+
moduleAToken := keeper.AllocHoldToken()
226+
moduleBToken := moduleAToken.AllocChainedToken()
227+
228+
// 模块A的关闭逻辑
229+
moduleAToken.DoOnShutdown(func(ctx context.Context) {
230+
fmt.Printf("模块A开始关闭...")
231+
// 模拟一些清理工作
232+
time.Sleep(2 * time.Second)
233+
fmt.Println("模块A关闭完成")
234+
})
235+
236+
// 模块B的关闭逻辑(会等待模块A关闭后才执行)
237+
moduleBToken.DoOnShutdown(func(ctx context.Context) {
238+
fmt.Printf("模块B开始关闭...")
239+
time.Sleep(1 * time.Second)
240+
fmt.Println("模块B关闭完成")
241+
})
242+
243+
fmt.Println("应用程序启动, 按 Ctrl+C 测试有序关闭")
244+
keeper.Wait()
245+
fmt.Println("应用程序已按顺序优雅退出")
246+
}
247+
```
248+
203249
## 常见问题
204250

205251
### Q: 为什么不直接使用 context.WithCancel?
@@ -210,6 +256,6 @@ A: Context 只能传递取消信号,但不能确保所有 goroutine 都完成了
210256

211257
A: 设置 `MaxHoldTime` 参数,超时后会强制退出.你也可以在每个模块内部设置自己的超时逻辑.
212258

213-
### Q: 可以在运行时动态分配 Token 吗?
259+
### Q: 可以在运行时动态分配 HoldToken 吗?
214260

215261
A: 可以!你可以随时调用 `AllocHoldToken()`,Keeper 会跟踪所有分配的 token.

0 commit comments

Comments
 (0)