Help us shape the future of Go! Take the 2026 Go Developer Survey

threshold

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 10, 2026 License: MIT Imports: 4 Imported by: 0

README

Threshold Executor 阈值执行器

数量阈值 + 周期兜底 的批量执行器: 数据量够了就立刻执行(低延迟), 数据量不够时由周期兜底执行(不饿死)。

import "github.com/474420502/execute/batch/threshold"

快速开始

exec := threshold.NewThresholdExecute[Log](func(batch []Log) error {
    return store.BatchInsert(batch) // 达到阈值时执行
}).
    WithBatchSize(128).            // 达到 128 条立即执行
    WithPeriodic(time.Second)      // 不足 128 条时, 最多攒 1 秒

defer exec.Wait(nil)

for _, l := range logs {
    exec.Collect(l)
}

两条触发路径

触发条件 使用的处理器 说明
缓冲区条数 >= BatchSize SizeHandler(默认 handler) 立即执行, 不等周期
周期到达且缓冲区非空 PeriodicHandler(默认 handler) 只处理不足阈值的残留数据
显式 Flush() PeriodicHandler 立即把残留数据刷出去

可以为两条路径配置不同处理器, 例如"阈值路径走批量写, 兜底路径走小批写 + 告警":

exec := threshold.NewThresholdExecute[Log](bulkInsert).
    WithBatchSize(1000).
    WithPeriodic(time.Second).
    WithBatchSizeHandler(bulkInsert).
    WithPeriodicHandler(func(batch []Log) error {
        log.Printf("兜底提交 %d 条(未达阈值)", len(batch))
        return bulkInsert(batch)
    })

关键行为

  • 采集永不与执行互锁: Collect 只入队, 不会因为处理器慢而与自己死锁; 处理器慢时表现为队列填满后的上游背压。
  • 数据切片复用: Handler 的入参仅在本次调用内有效, 需要保留请 slices.Clone。
  • 阈值热更新: WithBatchSize 在下一批数据上生效。
  • 周期热更新: WithPeriodic 立即按新周期重新计时。
  • 默认值: BatchSize = 128, Periodic = 100ms。

生命周期

ThresholdExecute 同时提供两套等价方法:

exec.Stop()      // 兼容用法: Close + Wait, 阻塞到全部结束
exec.Close()     // 优雅关闭(幂等, 不阻塞)
exec.Wait(ctx)   // 同步等待
exec.Collect(x)  // 关闭后返回 threshold/basic.ErrClosed

数量阈值触发但不立即执行?

仅在 Concurrent 并发模式下, 引擎默认把"数量阈值"推迟到下一个节拍统一切分批次, 避免到达速率波动导致并发批次数失控。阈值执行器始终使用"立即执行"语义。 如需在并发模式下改变该行为, 使用 engine.WithDeferOnThreshold[int](false) 显式声明。

Documentation

Overview

Package threshold 提供"数据积累到阈值或周期到达时执行"的批量执行器.

触发条件:

数量阈值: 缓冲区数据条数达到 BatchSize 时立即执行, 使用数量阈值回调;
周期兜底: 每隔 Periodic 把不足阈值的数据也执行掉, 使用周期回调。

两个条件可同时启用: 高流量时按量切批(低延迟), 低流量时由周期兜底(不饿死)。

Index

Examples

Constants

View Source
const (
	// BackpressureBlock 队列满时阻塞投递(默认, 不丢数据).
	BackpressureBlock = engine.BackpressureBlock
	// BackpressureDrop 队列满时丢弃并计数, 不阻塞调用方.
	BackpressureDrop = engine.BackpressureDrop
)

Variables

View Source
var (
	// ErrClosed 表示执行器已关闭, 不再接收数据.
	ErrClosed = basic.ErrClosed
	// ErrQueueFull 表示非阻塞收集时队列已满.
	ErrQueueFull = basic.ErrQueueFull
)

与执行器生命周期相关的错误, 便于调用方用 errors.Is 判定.

Functions

This section is empty.

Types

type Backpressure added in v0.3.0

type Backpressure = engine.Backpressure

Backpressure 是队列/并发槽位不足时的行为(阻塞或丢弃).

type Config added in v0.3.0

type Config[ITEM any] struct {
	// Handler 是默认处理器(同时作为数量阈值与周期兜底两条路径的默认值), 必填。
	Handler Handler[ITEM]
	// BatchSize 是数量阈值, <=0 时取默认值 128。
	BatchSize int
	// Periodic 是周期兜底间隔, <=0 时取默认值 100ms。
	Periodic time.Duration
	// SizeHandler 覆盖"达到数量阈值"路径的处理器(可选)。
	SizeHandler Handler[ITEM]
	// PeriodicHandler 覆盖"周期兜底"路径的处理器(可选)。
	PeriodicHandler Handler[ITEM]

	// QueueSize 是采集队列容量; <=0 时使用引擎默认值 65536。
	QueueSize int
	// BufferCap 是批次缓冲区初始容量; <=0 时自动推导。
	BufferCap int
	// Backpressure 决定队列满时的行为, 默认阻塞。
	Backpressure Backpressure
	// MaxPending 限制缓冲区积压上限, <=0 表示不限制。
	MaxPending int

	// Recover 在 Handler panic 时被调用(可选)。
	Recover RecoverFunc
	// OnExecute 在每次批次执行完成后同步回调(可选, 必须轻量)。
	OnExecute func(ExecuteEvent)
	// OnDrop 在每次丢弃数据时同步回调(可选, 必须轻量)。
	OnDrop func(DropEvent)
	// Name 用于日志与指标标识。
	Name string
}

Config 是阈值执行器的完整创建配置, 用于需要精细控制队列容量与背压的场景。

type DropEvent added in v0.3.0

type DropEvent = basic.DropEvent

DropEvent 是数据被丢弃时的观测事件(等价于 basic.DropEvent).

type ExecuteEvent added in v0.3.0

type ExecuteEvent = basic.ExecuteEvent

ExecuteEvent 是批次执行结果的观测事件(等价于 basic.ExecuteEvent).

type Func added in v0.3.0

type Func[ITEM any] func(items []ITEM)

Func 是不返回错误的便捷回调形式, 可通过 HandlerOf 包装成 Handler.

type Handler added in v0.3.0

type Handler[ITEM any] = basic.Handler[ITEM]

Handler 是阈值执行器的业务回调. items 仅在下一次执行前有效, 需要保留请自行复制.

func HandlerOf added in v0.3.0

func HandlerOf[ITEM any](fn Func[ITEM]) Handler[ITEM]

HandlerOf 把无返回值的回调包装成 Handler.

type RecoverFunc added in v0.3.0

type RecoverFunc = basic.RecoverFunc

RecoverFunc 是 panic 恢复回调(等价于 basic.RecoverFunc).

type ThresholdExecute

type ThresholdExecute[ITEM any] struct {
	*engine.Engine[ITEM]
}

ThresholdExecute 是阈值执行器.

默认 batchSize=128、periodic=100ms. 首次 Collect 时自动启动执行循环。

Example

ExampleThresholdExecute 演示阈值执行器: 高流量按量切批, 低流量由周期兜底.

package main

import (
	"fmt"
	"sync"
	"time"

	"github.com/474420502/execute/batch/threshold"
)

func main() {
	var (
		mu     sync.Mutex
		bySize []int
		byTick []int
	)

	// handler 同时作为数量阈值与周期兜底的默认处理器.
	exec := threshold.NewThresholdExecute[int](func(items []int) error {
		mu.Lock()
		bySize = append(bySize, items...)
		mu.Unlock()
		return nil
	}).
		WithBatchSize(3).
		WithPeriodic(50 * time.Millisecond).
		WithPeriodicHandler(func(items []int) error {
			mu.Lock()
			byTick = append(byTick, items...)
			mu.Unlock()
			return nil
		})
	defer func() { _ = exec.Wait(nil) }()

	// 前 3 条立即触发数量阈值.
	for i := 1; i <= 3; i++ {
		if err := exec.Collect(i); err != nil {
			fmt.Println("collect:", err)
			return
		}
	}
	if err := exec.Flush(); err != nil {
		fmt.Println("flush:", err)
		return
	}

	// 剩余不足阈值的数据由周期兜底处理.
	if err := exec.Collect(4); err != nil {
		fmt.Println("collect:", err)
		return
	}
	time.Sleep(120 * time.Millisecond)

	mu.Lock()
	fmt.Println("by size:", bySize)
	fmt.Println("by tick:", byTick)
	mu.Unlock()

}
Output:
by size: [1 2 3]
by tick: [4]

func NewFromConfig added in v0.3.0

func NewFromConfig[ITEM any](cfg Config[ITEM]) *ThresholdExecute[ITEM]

NewFromConfig 使用完整配置创建阈值执行器。

func NewThresholdExecute

func NewThresholdExecute[ITEM any](handler Handler[ITEM]) *ThresholdExecute[ITEM]

NewThresholdExecute 创建阈值执行器.

handler 接收达到数量阈值的批次(单个节拍可能包含多个批次)。

func (*ThresholdExecute[ITEM]) Stop

func (exec *ThresholdExecute[ITEM]) Stop()

Stop 停止执行器并等待在途任务与残留数据执行完成.

语义等价于 exec.Close() + exec.Wait(nil), 保留该方法是为了兼容既有调用习惯; 新代码推荐直接使用被提升的 Close/Wait.

func (*ThresholdExecute[ITEM]) WithBackpressure added in v0.3.0

func (exec *ThresholdExecute[ITEM]) WithBackpressure(bp Backpressure) *ThresholdExecute[ITEM]

WithBackpressure 设置背压策略(阻塞或丢弃), 运行期可热更新.

func (*ThresholdExecute[ITEM]) WithBatchSize added in v0.1.0

func (exec *ThresholdExecute[ITEM]) WithBatchSize(size int) *ThresholdExecute[ITEM]

WithBatchSize 设置数量阈值, 运行期可热更新(下一批生效).

func (*ThresholdExecute[ITEM]) WithBatchSizeHandler added in v0.1.0

func (exec *ThresholdExecute[ITEM]) WithBatchSizeHandler(handler Handler[ITEM]) *ThresholdExecute[ITEM]

WithBatchSizeHandler 设置"达到数量阈值"时的专用回调.

func (*ThresholdExecute[ITEM]) WithMaxPending added in v0.3.0

func (exec *ThresholdExecute[ITEM]) WithMaxPending(n int) *ThresholdExecute[ITEM]

WithMaxPending 设置缓冲区积压上限(<=0 表示不限制), 运行期可热更新.

func (*ThresholdExecute[ITEM]) WithOnDrop added in v0.3.0

func (exec *ThresholdExecute[ITEM]) WithOnDrop(fn func(DropEvent)) *ThresholdExecute[ITEM]

WithOnDrop 设置丢弃数据时的观测回调(同步调用, 需保持轻量).

func (*ThresholdExecute[ITEM]) WithOnExecute added in v0.3.0

func (exec *ThresholdExecute[ITEM]) WithOnExecute(fn func(ExecuteEvent)) *ThresholdExecute[ITEM]

WithOnExecute 设置批次执行完成观测回调(同步调用, 需保持轻量).

func (*ThresholdExecute[ITEM]) WithPeriodic added in v0.1.0

func (exec *ThresholdExecute[ITEM]) WithPeriodic(interval time.Duration) *ThresholdExecute[ITEM]

WithPeriodic 设置周期兜底间隔, 运行期可热更新(下一个网格点生效).

func (*ThresholdExecute[ITEM]) WithPeriodicHandler added in v0.1.0

func (exec *ThresholdExecute[ITEM]) WithPeriodicHandler(handler Handler[ITEM]) *ThresholdExecute[ITEM]

WithPeriodicHandler 设置"周期兜底"时的专用回调.

func (*ThresholdExecute[ITEM]) WithRecover added in v0.1.0

func (exec *ThresholdExecute[ITEM]) WithRecover(fn basic.RecoverFunc) *ThresholdExecute[ITEM]

WithRecover 设置 panic 恢复回调.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL