Documentation
¶
Overview ¶
Package triggered 提供被动触发式执行器.
与 batch/periodic、batch/threshold 不同, 它不使用任何定时器: 每次 Notify 数据到达时, 立即把"当前缓冲区中已有的全部数据"合并成一个批次执行, 因此天然具备合并突发流量(批量放大)的能力, 适合事件驱动、日志聚合、通知推送等场景.
执行函数是串行的: 同一时刻只有一个批次在执行, 上游可以放心地用 Notify 做背压。
Index ¶
- type Config
- type EventExecute
- func (exec *EventExecute[ITEM]) Notify(item ITEM) error
- func (exec *EventExecute[ITEM]) Shared() *Share
- func (exec *EventExecute[ITEM]) TryNotify(item ITEM) error
- func (exec *EventExecute[ITEM]) WithOnExecute(fn func(basic.ExecuteEvent)) *EventExecute[ITEM]
- func (exec *EventExecute[ITEM]) WithRecover(fn basic.RecoverFunc) *EventExecute[ITEM]
- func (exec *EventExecute[ITEM]) WithShared(v any) *EventExecute[ITEM]
- type Handler
- type Items
- type Share
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶ added in v0.3.0
type Config[ITEM any] struct { // ItemsChanSize 是 Notify 队列容量; <=0 时取默认值 1024. ItemsChanSize int // QueueSize 是执行器采集队列容量; <=0 时与 ItemsChanSize 一致. QueueSize int // ExecuteDo 是业务回调, 必填. ExecuteDo Handler[ITEM] Shared *Share // Recover 是 panic 恢复回调(可选). Recover basic.RecoverFunc // Backpressure 决定队列满时 Notify 的行为, 默认 BackpressureBlock. Backpressure engine.Backpressure // MaxPending 限制缓冲区积压; <=0 不限制. MaxPending int // Name 用于日志与指标标识. Name string }
Config 是 RegisterExecuteEx 的完整配置.
type EventExecute ¶ added in v0.0.3
type EventExecute[ITEM any] struct { *engine.Engine[ITEM] // contains filtered or unexported fields }
EventExecute 是被动触发式执行器.
生命周期: 创建即开始接收 Notify, 首次数据到达即执行; Close 幂等, Close 之后 Notify 返回 basic.ErrClosed(err 不再 panic).
func RegisterExecute ¶ added in v0.0.3
func RegisterExecute[ITEM any](execDo Handler[ITEM]) *EventExecute[ITEM]
RegisterExecute 注册一个执行单元.
等价于 RegisterExecuteEx(&Config{ExecuteDo: execDo})。
Example ¶
ExampleRegisterExecute 演示事件触发执行器: 数据到达即执行(把当时缓冲区内的数据合成一个批次), 并可在批次之间共享状态。
package main
import (
"fmt"
"sync"
"github.com/474420502/execute/triggered"
)
func main() {
var (
mu sync.Mutex
batches int
received []int
)
done := make(chan struct{})
exec := triggered.RegisterExecute[int](func(items *triggered.Items[int]) error {
mu.Lock()
batches++
received = append(received, items.Value...)
total, _ := items.Shared.Load().(int)
items.Shared.Store(total + items.Len()) // 跨批次累计
mu.Unlock()
if items.Len() == 2 {
select {
case <-done:
default:
close(done)
}
}
return nil
}).WithShared(0)
defer func() { _ = exec.Wait(nil) }()
// Notify 把数据放入有界队列; 队列未满时不会阻塞.
for i := 1; i <= 4; i++ {
if err := exec.Notify(i); err != nil {
fmt.Println("notify:", err)
return
}
}
if err := exec.Flush(); err != nil { // 等待所有已投递数据执行完成
fmt.Println("flush:", err)
return
}
mu.Lock()
fmt.Println("batches:", batches)
fmt.Println("received:", received)
fmt.Println("shared:", exec.Shared().Load())
mu.Unlock()
}
Output: batches: 4 received: [1 2 3 4] shared: 4
func RegisterExecuteEx ¶ added in v0.3.0
func RegisterExecuteEx[ITEM any](cfg *Config[ITEM]) *EventExecute[ITEM]
RegisterExecuteEx 使用完整配置注册执行单元.
Example ¶
ExampleRegisterExecuteEx 演示带配置的注册方式与优雅关闭.
package main
import (
"fmt"
"github.com/474420502/execute/triggered"
)
func main() {
var count int
exec := triggered.RegisterExecuteEx(&triggered.Config[int]{
ItemsChanSize: 128, // Notify 队列容量
Name: "example",
ExecuteDo: func(items *triggered.Items[int]) error {
count += items.Len()
return nil
},
})
defer func() { _ = exec.Wait(nil) }()
if err := exec.Notify(1); err != nil {
fmt.Println("notify:", err)
}
if err := exec.Flush(); err != nil {
fmt.Println("flush:", err)
}
exec.Close()
exec.Close() // 幂等
fmt.Println("count:", count)
// 关闭之后投递会返回 ErrClosed, 而不是 panic.
fmt.Println("after close:", exec.Notify(2))
}
Output: count: 1 after close: execute: executor is closed
func (*EventExecute[ITEM]) Notify ¶ added in v0.0.3
func (exec *EventExecute[ITEM]) Notify(item ITEM) error
Notify 投递一条事件. 队列满时按背压策略阻塞, 执行器已关闭时返回 basic.ErrClosed.
与历史行为一致: 突发投递的多条事件会被合并为一个批次执行。
func (*EventExecute[ITEM]) Shared ¶ added in v0.3.0
func (exec *EventExecute[ITEM]) Shared() *Share
Shared 返回该执行器的共享状态载体.
func (*EventExecute[ITEM]) TryNotify ¶ added in v0.3.0
func (exec *EventExecute[ITEM]) TryNotify(item ITEM) error
TryNotify 非阻塞投递; 队列满时返回 basic.ErrQueueFull 并计入丢弃指标.
func (*EventExecute[ITEM]) WithOnExecute ¶ added in v0.3.0
func (exec *EventExecute[ITEM]) WithOnExecute(fn func(basic.ExecuteEvent)) *EventExecute[ITEM]
WithOnExecute 设置批次执行完成观测回调(同步调用, 需保持轻量).
func (*EventExecute[ITEM]) WithRecover ¶ added in v0.1.0
func (exec *EventExecute[ITEM]) WithRecover(fn basic.RecoverFunc) *EventExecute[ITEM]
WithRecover 设置 panic 恢复回调.
func (*EventExecute[ITEM]) WithShared ¶ added in v0.1.0
func (exec *EventExecute[ITEM]) WithShared(v any) *EventExecute[ITEM]
WithShared 设置共享状态, 并返回自身以便链式调用.
type Handler ¶ added in v0.3.0
Handler 是触发式执行器的业务回调.
items.Value 仅在本批次的执行期间有效: 需要跨批次保留数据时请复制或保存 Shared 中的引用。items.Shared 是从执行器创建起就存在、跨批次共享的状态载体。
type Items ¶ added in v0.3.0
type Items[T any] struct { // Value 是本批次的数据, 仅在本次执行期间有效. Value []T Shared *Share // contains filtered or unexported fields }
Items 是一次执行的上下文: 本批次数据 + 跨批次共享状态.
type Share ¶ added in v0.3.0
type Share struct {
// contains filtered or unexported fields
}
Share 是跨批次共享的状态载体, 可安全地被多个 goroutine 并发访问.
存取值有两种风格, 按需选择:
原子风格: Load/Store/CompareAndSwap/Swap —— 适合标量配置、开关、版本号; 回调风格: Value/SetValue —— 与历史 API 兼容, 在锁内访问复合结构.
func (*Share) CompareAndSwap ¶ added in v0.3.0
CompareAndSwap 原子比较并交换; 仅当当前值 == old 时写入 new 并返回 true.