Making Sense Golang Worker Pattern

Published: (February 26, 2026 at 05:37 AM EST)
2 min read
Source: Dev.to

Source: Dev.to

Spawn workers

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
}

Three goroutine workers are started; each reads from a channel of StudentItem values and reports errors via errCh.

Publish task/job to workers

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
    }
}

The caller fills a buffered channel with all StudentItem jobs and then closes it. Workers pull jobs from this read‑only channel (data <-chan models.StudentItem) and process them concurrently.

Collecting results

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
    }
}

Each worker sends its result (or error) to a write‑only channel (errCh). Because the caller knows how many jobs were dispatched, it reads exactly that many results, handling any errors without needing to know which specific worker produced them.

0 views
Back to Blog

Related posts

Read more »

Allocating on the Stack

The Go Blog Allocating on the Stack We’re always looking for ways to make Go programs faster. In the last two releases we have concentrated on mitigating a par...