-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
237 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: Format Check | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
check-format: | ||
name: Check Go Format | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout Code | ||
uses: actions/checkout@v3 | ||
|
||
- name: Set up Go | ||
uses: actions/setup-go@v4 | ||
with: | ||
go-version: 1.21 # Update with your Go version | ||
|
||
- name: Install Make (if needed) | ||
run: sudo apt-get install -y make | ||
|
||
- name: Run Format Check using Makefile | ||
run: make check | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Check if all Go files are formatted | ||
check: | ||
@OUTPUT=$$(gofmt -l .); \ | ||
if [ -n "$$OUTPUT" ]; then \ | ||
echo "The following files are not formatted. Run 'make format' to fix them:"; \ | ||
echo "$$OUTPUT"; \ | ||
exit 1; \ | ||
fi | ||
|
||
# Format all Go files | ||
format: | ||
gofmt -w . | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"sync" | ||
) | ||
|
||
// Task is a function that returns an error | ||
type Task func() error | ||
|
||
// WorkerPool processes tasks concurrently using a fixed number of workers. | ||
func WorkerPool(tasks []Task, workerCount int) []error { | ||
var wg sync.WaitGroup | ||
taskCh := make(chan Task) | ||
errCh := make(chan error, len(tasks)) // Buffered to hold all potential errors | ||
|
||
// Start workers | ||
for i := 0; i < workerCount; i++ { | ||
wg.Add(1) | ||
go func() { | ||
defer wg.Done() | ||
for task := range taskCh { | ||
if err := task(); err != nil { | ||
errCh <- err | ||
} | ||
} | ||
}() | ||
} | ||
|
||
// Send tasks to the taskCh | ||
go func() { | ||
for _, task := range tasks { | ||
taskCh <- task | ||
} | ||
close(taskCh) | ||
}() | ||
|
||
// Wait for all workers to finish | ||
wg.Wait() | ||
close(errCh) | ||
|
||
// Collect errors | ||
var errors []error | ||
for err := range errCh { | ||
errors = append(errors, err) | ||
} | ||
|
||
return errors | ||
} | ||
|
||
func main() { | ||
// Example tasks | ||
tasks := []Task{ | ||
func() error { return nil }, | ||
func() error { return errors.New("Task 2 failed") }, | ||
func() error { return nil }, | ||
func() error { return errors.New("Task 4 failed") }, | ||
} | ||
|
||
// Run WorkerPool | ||
workerCount := 3 | ||
errors := WorkerPool(tasks, workerCount) | ||
|
||
// Print results | ||
if len(errors) == 0 { | ||
fmt.Println("All tasks completed successfully") | ||
} else { | ||
fmt.Println("Errors:") | ||
for _, err := range errors { | ||
fmt.Println(err) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"sync" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestNoChannelExample(t *testing.T) { | ||
go func() { | ||
fmt.Println("Running without channels") | ||
time.Sleep(1 * time.Second) | ||
}() | ||
time.Sleep(2 * time.Second) | ||
fmt.Println("No-channel example done") | ||
} | ||
|
||
func TestChannelExample(t *testing.T) { | ||
ch := make(chan string) | ||
go func() { ch <- "Running with goroutine" }() | ||
fmt.Println(<-ch) | ||
fmt.Println("Channel example done") | ||
} | ||
|
||
func TestWorkerPool_Success(t *testing.T) { | ||
tasks := []Task{ | ||
func() error { return nil }, | ||
func() error { return nil }, | ||
func() error { return nil }, | ||
} | ||
|
||
workerCount := 2 | ||
errors := WorkerPool(tasks, workerCount) | ||
|
||
if len(errors) != 0 { | ||
t.Fatalf("expected no errors, got %d errors: %v", len(errors), errors) | ||
} | ||
} | ||
|
||
func TestWorkerPool_Errors(t *testing.T) { | ||
// Create tasks with some failures | ||
tasks := []Task{ | ||
func() error { return errors.New("Task 1 failed") }, | ||
func() error { return nil }, | ||
func() error { return errors.New("Task 3 failed") }, | ||
} | ||
|
||
workerCount := 3 | ||
errors := WorkerPool(tasks, workerCount) | ||
|
||
// Verify the correct number of errors | ||
if len(errors) != 2 { | ||
t.Fatalf("expected 2 errors, got %d: %v", len(errors), errors) | ||
} | ||
} | ||
|
||
func TestWorkerPool_Concurrency(t *testing.T) { | ||
var mu sync.Mutex | ||
taskOrder := []int{} | ||
|
||
// Create tasks that add their index to the taskOrder slice | ||
tasks := []Task{ | ||
func() error { | ||
mu.Lock() | ||
taskOrder = append(taskOrder, 1) | ||
mu.Unlock() | ||
return nil | ||
}, | ||
func() error { | ||
mu.Lock() | ||
taskOrder = append(taskOrder, 2) | ||
mu.Unlock() | ||
return nil | ||
}, | ||
func() error { | ||
mu.Lock() | ||
taskOrder = append(taskOrder, 3) | ||
mu.Unlock() | ||
return nil | ||
}, | ||
} | ||
|
||
workerCount := 2 | ||
_ = WorkerPool(tasks, workerCount) | ||
|
||
// Verify that all tasks were executed | ||
if len(taskOrder) != len(tasks) { | ||
t.Fatalf("expected %d tasks to be executed, but got %d", len(tasks), len(taskOrder)) | ||
} | ||
} | ||
|
||
func TestWorkerPool_NoTasks(t *testing.T) { | ||
// Empty task list | ||
tasks := []Task{} | ||
|
||
workerCount := 3 | ||
errors := WorkerPool(tasks, workerCount) | ||
|
||
// No errors should occur since no tasks exist | ||
if len(errors) != 0 { | ||
t.Fatalf("expected no errors, got %d: %v", len(errors), errors) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module concurrency | ||
|
||
go 1.23.3 | ||
|
||
require ( | ||
golang.org/x/mod v0.22.0 // indirect | ||
golang.org/x/sync v0.10.0 // indirect | ||
golang.org/x/tools v0.28.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= | ||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= | ||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= | ||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= | ||
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= | ||
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= |