Skip to content

Commit

Permalink
fix #2: implement safe.Job
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilsk committed Mar 14, 2020
1 parent e93352a commit c0bd00a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 21 deletions.
35 changes: 19 additions & 16 deletions safe/background.go
Expand Up @@ -2,31 +2,34 @@ package safe

import "sync"

type Job interface {
Do(func() error, func(error))
Wait()
}

func Background() Job {
return &background{}
}

type background sync.WaitGroup
// A Job provides a top level API above the sync.WaitGroup.
//
// job := new(safe.Job)
// for _, action := range jobs {
// job.Do(action, logger)
// }
// job.Wait()
//
// It looks a little bit similar to the golang.org/x/sync/errgroup.
type Job sync.WaitGroup

func (bg *background) Do(action func() error, handler func(error)) {
(*sync.WaitGroup)(bg).Add(1)
// Do calls the given function in a new goroutine.
// If an error is not nil, it passes it to the handler.
func (job *Job) Do(action func() error, handler func(error)) {
(*sync.WaitGroup)(job).Add(1)
go Do(func() error {
if err := action(); err != nil {
return err
}
(*sync.WaitGroup)(bg).Done()
(*sync.WaitGroup)(job).Done()
return nil
}, func(err error) {
handler(err)
(*sync.WaitGroup)(bg).Done()
(*sync.WaitGroup)(job).Done()
})
}

func (bg *background) Wait() {
(*sync.WaitGroup)(bg).Wait()
// Wait blocks until the sync.WaitGroup counter is zero.
func (job *Job) Wait() {
(*sync.WaitGroup)(job).Wait()
}
10 changes: 5 additions & 5 deletions safe/background_test.go
Expand Up @@ -11,10 +11,10 @@ import (
. "go.octolab.org/safe"
)

func TestBackground(t *testing.T) {
func TestJob(t *testing.T) {
var spy uint32

job := Background()
job := new(Job)
for range make([]struct{}, 10) {
job.Do(func() error {
atomic.AddUint32(&spy, 1)
Expand Down Expand Up @@ -43,23 +43,23 @@ func BenchmarkBackground(b *testing.B) {
b.Run("without error", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
job := Background()
job := new(Job)
job.Do(func() error { return nil }, nil)
job.Wait()
}
})
b.Run("with error", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
job := Background()
job := new(Job)
job.Do(func() error { return errors.New("test") }, func(error) {})
job.Wait()
}
})
b.Run("with panic", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
job := Background()
job := new(Job)
job.Do(func() error { panic(errors.New("at the Disco")) }, func(error) {})
job.Wait()
}
Expand Down

0 comments on commit c0bd00a

Please sign in to comment.