理解 Golang Worker Pattern

发布: (2026年2月26日 GMT+8 18:37)
2 分钟阅读
原文: Dev.to

Source: Dev.to

启动工作者

intNumWorkers := 3

for w := 0; w < intNumWorkers; w++ {
    go InsertStudentData(ctx, tx, insertedStudentJobs, insertedStudentjobsErrCh)
}
func InsertStudentData(ctx context.Context, tx *sql.Tx, data <-chan models.StudentItem, errCh chan<- error) {
    // worker implementation
}

启动了三个 goroutine 工作者;每个工作者从 StudentItem 值的通道中读取数据,并通过 errCh 上报错误。

向工作者发布任务/作业

numJobs := len(StudentItems)
jobs := make(chan models.StudentItem, numJobs)

for i := 0; i < numJobs; i++ {
    jobs <- StudentItems[i]
}
close(jobs)
func InsertStudentWorker(ctx context.Context, tx *sql.Tx, data <-chan models.StudentItem, errCh chan<- error) {
    for d := range data {
        err := repository.InsertStudentItemFromWorker(ctx, tx, d)
        // handle err if needed
    }
}

调用方用所有 StudentItem 作业填充一个带缓冲的通道,然后关闭它。工作者从只读通道 (data <-chan models.StudentItem) 中获取作业并并发处理。

收集结果

numJobs := len(StudentItems)
jobs := make(chan models.StudentItem, numJobs)

for i := 0; i < numJobs; i++ {
    jobs <- StudentItems[i]
}
close(jobs)

// read from the error channel
for j := 0; j < numJobs; j++ {
    err := <-jobsErrCh
    if err != nil {
        _ = tx.Rollback()
        return err
    }
}
func InsertStudentWorker(ctx context.Context, tx *sql.Tx, data <-chan models.StudentItem, errCh chan<- error) {
    for d := range data {
        err := repository.InsertStudentItemFromWorker(ctx, tx, d)
        errCh <- err
    }
}

每个工作者将其结果(或错误)发送到只写通道 (errCh)。由于调用方知道已分发的作业数量,它会读取恰好相同数量的结果,处理任何错误,而无需了解是哪一个具体工作者产生的。

0 浏览
Back to Blog

相关文章

阅读更多 »

国家疫苗预约与接种系统

🌱 它是如何开始的 几年前,我参加了一场系统设计面试。面试官给了我这样一个情景:> 设计一个全国疫苗预约系统…