From 9ed5a2f85af06798bdcd61373059523ef300111a Mon Sep 17 00:00:00 2001 From: Konstantin Grachev Date: Thu, 15 Feb 2024 18:39:41 +0300 Subject: [PATCH] worker-pool: init --- worker-pool/Makefile | 53 ++++++++++++++++++++++++++++++++++++++++ worker-pool/go.mod | 11 +++++++++ worker-pool/main.go | 21 ++++++++++++++++ worker-pool/main_test.go | 41 +++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 worker-pool/Makefile create mode 100644 worker-pool/go.mod create mode 100644 worker-pool/main.go create mode 100644 worker-pool/main_test.go diff --git a/worker-pool/Makefile b/worker-pool/Makefile new file mode 100644 index 0000000..977c1c9 --- /dev/null +++ b/worker-pool/Makefile @@ -0,0 +1,53 @@ +.DEFAULT_GOAL := help + +# ==================================================================================== # +# HELPERS +# ==================================================================================== # + +## help: print this help message +.PHONY: help +help: + @echo 'Usage:' + @sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /' + +## all: tidy + audit + test/cover +all: generate tidy test lint test/cover + + +# ==================================================================================== # +# QUALITY CONTROL +# ==================================================================================== # + +## tidy: format code and tidy modfile +.PHONY: tidy +tidy: + go fmt ./... + goimports -local=$(shell cat go.mod | grep module | awk '{print $$2}')/ -w . + go mod tidy -v + +## audit: run quality control checks +.PHONY: lint +lint: + go mod verify + go run github.com/golangci/golangci-lint/cmd/golangci-lint@latest run -v ./... + + +# ==================================================================================== # +# DEVELOPMENT +# ==================================================================================== # + +## generate: run all generators +.PHONY: generate +generate: + go generate ./... + +## test: run all tests +.PHONY: test +test: + go test -race -buildvcs ./... + +## test/cover: run all tests and display coverage +.PHONY: test/cover +test/cover: + go test -race -buildvcs -coverprofile=/tmp/coverage.out ./... + go tool cover -html=/tmp/coverage.out diff --git a/worker-pool/go.mod b/worker-pool/go.mod new file mode 100644 index 0000000..a01eea9 --- /dev/null +++ b/worker-pool/go.mod @@ -0,0 +1,11 @@ +module worker-pool + +go 1.21.6 + +require github.com/stretchr/testify v1.8.4 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/worker-pool/main.go b/worker-pool/main.go new file mode 100644 index 0000000..1abe752 --- /dev/null +++ b/worker-pool/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" +) + +func WorkerPool[T any](limit int, worker func(int, T)) chan<- T { + tasks := make(chan T, limit) + + for i := 1; i <= limit; i++ { + go func(i int) { + defer fmt.Printf("worker:%d done\n", i) + + for t := range tasks { + worker(i, t) + } + }(i) + } + + return tasks +} diff --git a/worker-pool/main_test.go b/worker-pool/main_test.go new file mode 100644 index 0000000..1511387 --- /dev/null +++ b/worker-pool/main_test.go @@ -0,0 +1,41 @@ +package main + +import ( + "fmt" + "sync" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestWorkerPool(t *testing.T) { + const tasks = 5 + + var wg sync.WaitGroup + wg.Add(tasks) + + var mt sync.Mutex + done := make(map[int]bool, tasks) + + worker := func(pid int, task int) { + defer wg.Done() + + mt.Lock() + done[pid] = true + mt.Unlock() + + fmt.Printf("task:%+v\n", task) + } + + pool := WorkerPool(tasks, worker) + + for j := 0; j < tasks; j++ { + pool <- j + } + close(pool) + wg.Wait() + + for _, v := range done { + assert.True(t, v) + } +}