Flowmatic:Go语言中结构化并发库


Flowmatic 是一个通用的 Go 库,它提供了一种类似Nurseries的结构化并发编程方法。它让你能够以简单、有效且灵活的方式轻松管理并发任务。

Flowmatic 拥有易于使用的 API,其中包含处理常见并发模式的函数。它会自动处理生成工作程序、收集错误和传播恐慌。

Flowmatic 需要 Go 1.20+。

特征

  • 具有简单的 API,可提高通道/等待组/互斥的可读性
  • 处理各种并发问题,如异构任务组、切片上任务的同质执行以及动态工作生成
  • 汇总错误
  • 正确地跨 goroutine 边界传播恐慌
  • 有上下文取消助手
  • 依赖性低
  • 良好的测试覆盖率

Flowmatic 能解决的一个问题是管理多个相互独立的任务的并行执行。例如,假设您要向三个不同的下游应用程序接口发送数据。如果任何一个发送失败,您都希望返回错误信息。如果使用传统的 Go 并发功能,这很快就会变得复杂而难以管理,因为需要跟踪 Goroutines、channel 和 sync.WaitGroups。

Flowmatic 让这一切变得简单。

err := flowmatic.Do(
    func() error {
        return doThingA(),
    },
    func() error {
        return doThingB(),
    },
    func() error {
        return doThingC(),
    })

使用stdlib传统:

var wg sync.WaitGroup
var errs []error
errChan := make(chan error)

wg.Add(3)
go func() {
    defer wg.Done()
    if err := doThingA(); err != nil {
        errChan <- err
    }
}()
go func() {
    defer wg.Done()
    if err := doThingB(); err != nil {
        errChan <- err
    }
}()
go func() {
    defer wg.Done()
    if err := doThingC(); err != nil {
        errChan <- err
    }
}()

go func() {
    wg.Wait()
    close(errChan)
}()

for err := range errChan {
    errs = append(errs, err)
}

err := errors.Join(errs...)


panic
在 Go 中,如果 goroutine 中出现 panic,并且该 panic 未被恢复,则整个进程将关闭。这种方法有利有弊。优点是,如果 panic 是应用程序中编程错误的症状,则应用程序不会造成进一步的损害。缺点是,在许多情况下,这会导致在可能可恢复的情况下关闭。

因此,虽然 Go 标准 HTTP 服务器会捕获在其某个 HTTP 处理程序中发生的错误并继续提供请求,但是标准 Go HTTP 服务器无法捕获在单独的 goroutine 中发生的错误,而这些错误将导致整个服务器离线。

Flowmatic 通过捕获在其一个工作 goroutine 中发生的panic并在父 goroutine 中重新传播它来解决此问题,以便可以在适当的级别捕获和记录panic。

背景:
这篇文章认为:
Go在没有结构化控制流的情况下生成并发任务是有害的,会导致诸如资源清理不当、错误处理问题以及并发代码推理困难等问题。

  • Go 语句中断自动资源清理:使用 go 语句生成任务时,没有自动方法确保任务完成后正确清理这些任务使用的资源。这需要手动实现资源清理,这很容易出错。
  • Go 语句中断错误处理:现代语言提供了强大的错误处理机制,例如异常。然而,这些机制依赖于“当前调用者”这一可靠的概念,而当使用 go 语句生成任务时,这一概念就会失效。这会导致未处理的错误被默默丢弃。

Nurseries 结构化并发:

  • Nurseries 允许生成多个并发任务,但确保在nurseries 退出之前将它们重新连接在一起。这为并发操作提供了明确的控制流结构。
  • Nurseries 允许在退出时自动清理资源,并传播错误以在 Nurseries 创建时进行处理。这可恢复错误处理并使并发代码推理变得更容易。

并发框架不应该采用可以在任何地方生成任务的原始“go”操作,而应该从头开始构建像Nurseries 托儿所这样的结构化构造。