Skip to content

Commit

Permalink
Add Group
Browse files Browse the repository at this point in the history
  • Loading branch information
aopoltorzhicky committed Aug 26, 2023
1 parent 7597af8 commit cbebf37
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
go-version: '1.19'
go-version: '1.20'
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
Expand Down
94 changes: 93 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,96 @@ type Dispatcher[Task any] func(ctx context.Context) ([]Task, error)
type ErrorHandler[Task any] func(ctx context.Context, err error)
```

Also it receives 2 integers: workers count and time between dispatcher calls in milliseconds.
Also it receives 2 integers: workers count and time between dispatcher calls in milliseconds.

# Group

`Group` can be used for running processes with wait group. For example:

```go
// this program runs 2 ticker functions and waits its executed.
func main() {
group := NewGroup()
group.Go(ticker3)
group.Go(ticker4)
group.Wait()
}

func ticker3() {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()

var count int

for range ticker.C {
count++
log.Print("second")

if count == 5 {
return
}
}
}

func ticker4() {
ticker := time.NewTicker(time.Second * 2)
defer ticker.Stop()

var count int

for range ticker.C {
count++
log.Print("2 second")

if count == 5 {
return
}
}
}
```

With using context:

```go
// the program runs two tickers and after 10 seconds cancel it using context cancellation
func main() {
ctx, cancel := context.WithCancel(context.Background())

group := NewGroup()
group.GoCtx(ctx, ticker1)
group.GoCtx(ctx, ticker2)

time.Sleep(10 * time.Second)
cancel()

group.Wait()
}

func ticker1(ctx context.Context) {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()

for {
select {
case <-ctx.Done():
return
case <-ticker.C:
log.Print("second")
}
}
}

func ticker2(ctx context.Context) {
ticker := time.NewTicker(time.Second * 2)
defer ticker.Stop()

for {
select {
case <-ctx.Done():
return
case <-ticker.C:
log.Print("2 second")
}
}
}
```
41 changes: 41 additions & 0 deletions group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package workerpool

import (
"context"
"sync"
)

// Runs functions with one wait group
type Group struct {
wg *sync.WaitGroup
}

// NewGroup - creates new Group
func NewGroup() Group {
return Group{
wg: new(sync.WaitGroup),
}
}

// Go - runs function with wait group
func (g Group) Go(f func()) {
g.wg.Add(1)
go func() {
defer g.wg.Done()
f()
}()
}

// GoCtx - runs function with wait group using context
func (g Group) GoCtx(ctx context.Context, f func(ctx context.Context)) {
g.wg.Add(1)
go func() {
defer g.wg.Done()
f(ctx)
}()
}

// Wait - waits until grouped functions end
func (g Group) Wait() {
g.wg.Wait()
}
88 changes: 88 additions & 0 deletions group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package workerpool

import (
"context"
"log"
"testing"
"time"
)

func TestGroupWithContext(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())

group := NewGroup()
group.GoCtx(ctx, ticker1)
group.GoCtx(ctx, ticker2)

time.Sleep(10 * time.Second)
cancel()

group.Wait()
}

func ticker1(ctx context.Context) {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()

for {
select {
case <-ctx.Done():
return
case <-ticker.C:
log.Print("second")
}
}
}

func ticker2(ctx context.Context) {
ticker := time.NewTicker(time.Second * 2)
defer ticker.Stop()

for {
select {
case <-ctx.Done():
return
case <-ticker.C:
log.Print("2 second")
}
}
}

func TestGroup(t *testing.T) {
group := NewGroup()
group.Go(ticker3)
group.Go(ticker4)
group.Wait()
}

func ticker3() {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()

var count int

for range ticker.C {
count++
log.Print("second")

if count == 5 {
return
}
}
}

func ticker4() {
ticker := time.NewTicker(time.Second * 2)
defer ticker.Stop()

var count int

for range ticker.C {
count++
log.Print("2 second")

if count == 5 {
return
}
}
}

0 comments on commit cbebf37

Please sign in to comment.