Skip to content

Commit

Permalink
Merge pull request #35 from freerware/freer/introduce-concurrency-saf…
Browse files Browse the repository at this point in the history
…eness

Modify 'Add', 'Alter', 'Remove', and 'Register' to support concurrency.
  • Loading branch information
fr33r committed Jul 27, 2020
2 parents f0ea090 + af0ecfb commit e94b202
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ bins:
test: bins
@echo testing...
@#v1
@GO111MODULE=on go test -v -covermode=count -coverprofile=coverage.out github.com/freerware/work
@GO111MODULE=on go test -v -race -covermode=atomic -coverprofile=coverage.out github.com/freerware/work
@#v3
@cd ./v3 && GO111MODULE=on go test -v -covermode=count -coverprofile=coverage.out github.com/freerware/work/v3 && cd ..
@cd ./v3 && GO111MODULE=on go test -v -race -covermode=atomic -coverprofile=coverage.out github.com/freerware/work/v3 && cd ..
@echo done!

mocks:
Expand Down
8 changes: 8 additions & 0 deletions v3/best_effort_unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ func (u *bestEffortUnit) applyDeletes() (err error) {
// Register tracks the provided entities as clean.
func (u *bestEffortUnit) Register(entities ...interface{}) error {
c := func(t TypeName) bool {
u.mutex.RLock()
_, ok := u.mappers[t]
u.mutex.RUnlock()
return ok
}
return u.register(c, entities...)
Expand All @@ -226,7 +228,9 @@ func (u *bestEffortUnit) Register(entities ...interface{}) error {
// Add marks the provided entities as new additions.
func (u *bestEffortUnit) Add(entities ...interface{}) error {
c := func(t TypeName) bool {
u.mutex.RLock()
_, ok := u.mappers[t]
u.mutex.RUnlock()
return ok
}
return u.add(c, entities...)
Expand All @@ -235,7 +239,9 @@ func (u *bestEffortUnit) Add(entities ...interface{}) error {
// Alter marks the provided entities as modifications.
func (u *bestEffortUnit) Alter(entities ...interface{}) error {
c := func(t TypeName) bool {
u.mutex.RLock()
_, ok := u.mappers[t]
u.mutex.RUnlock()
return ok
}
return u.alter(c, entities...)
Expand All @@ -244,7 +250,9 @@ func (u *bestEffortUnit) Alter(entities ...interface{}) error {
// Remove marks the provided entities as removals.
func (u *bestEffortUnit) Remove(entities ...interface{}) error {
c := func(t TypeName) bool {
u.mutex.RLock()
_, ok := u.mappers[t]
u.mutex.RUnlock()
return ok
}
return u.remove(c, entities...)
Expand Down
101 changes: 101 additions & 0 deletions v3/best_effort_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package work_test
import (
"errors"
"fmt"
"sync"
"testing"

"github.com/freerware/work/v3"
Expand Down Expand Up @@ -686,6 +687,31 @@ func (s *BestEffortUnitTestSuite) TestBestEffortUnit_Add() {
s.NoError(err)
}

func (s *BestEffortUnitTestSuite) TestBestEffortUnit_ConcurrentAdd() {

// arrange.
foo := Foo{ID: 28}
bar := Bar{ID: "28"}

// action.
var err, err2 error
var wg sync.WaitGroup
wg.Add(2)
go func() {
err = s.sut.Add(foo)
wg.Done()
}()
go func() {
err2 = s.sut.Add(bar)
wg.Done()
}()
wg.Wait()

// assert.
s.NoError(err)
s.NoError(err2)
}

func (s *BestEffortUnitTestSuite) TestBestEffortUnit_Alter_Empty() {

// arrange.
Expand Down Expand Up @@ -733,6 +759,31 @@ func (s *BestEffortUnitTestSuite) TestBestEffortUnit_Alter() {
s.NoError(err)
}

func (s *BestEffortUnitTestSuite) TestBestEffortUnit_ConcurrentAlter() {

// arrange.
foo := Foo{ID: 28}
bar := Bar{ID: "28"}

// action.
var err, err2 error
var wg sync.WaitGroup
wg.Add(2)
go func() {
err = s.sut.Alter(foo)
wg.Done()
}()
go func() {
err2 = s.sut.Alter(bar)
wg.Done()
}()
wg.Wait()

// assert.
s.NoError(err)
s.NoError(err2)
}

func (s *BestEffortUnitTestSuite) TestBestEffortUnit_Remove_Empty() {

// arrange.
Expand Down Expand Up @@ -780,6 +831,31 @@ func (s *BestEffortUnitTestSuite) TestBestEffortUnit_Remove() {
s.NoError(err)
}

func (s *BestEffortUnitTestSuite) TestBestEffortUnit_ConcurrentRemove() {

// arrange.
foo := Foo{ID: 28}
bar := Bar{ID: "28"}

// action.
var err, err2 error
var wg sync.WaitGroup
wg.Add(2)
go func() {
err = s.sut.Remove(foo)
wg.Done()
}()
go func() {
err2 = s.sut.Remove(bar)
wg.Done()
}()
wg.Wait()

// assert.
s.NoError(err)
s.NoError(err2)
}

func (s *BestEffortUnitTestSuite) TestBestEffortUnit_Register_Empty() {

// arrange.
Expand Down Expand Up @@ -828,6 +904,31 @@ func (s *BestEffortUnitTestSuite) TestBestEffortUnit_Register() {
s.NoError(err)
}

func (s *BestEffortUnitTestSuite) TestBestEffortUnit_ConcurrentRegister() {

// arrange.
foo := Foo{ID: 28}
bar := Bar{ID: "28"}

// action.
var err, err2 error
var wg sync.WaitGroup
wg.Add(2)
go func() {
err = s.sut.Register(foo)
wg.Done()
}()
go func() {
err2 = s.sut.Register(bar)
wg.Done()
}()
wg.Wait()

// assert.
s.NoError(err)
s.NoError(err2)
}

func (s *BestEffortUnitTestSuite) TearDownTest() {
s.sut = nil
s.mc.Finish()
Expand Down
8 changes: 8 additions & 0 deletions v3/sql_unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ func NewSQLUnit(
// Register tracks the provided entities as clean.
func (u *sqlUnit) Register(entities ...interface{}) error {
c := func(t TypeName) bool {
u.mutex.RLock()
_, ok := u.mappers[t]
u.mutex.RUnlock()
return ok
}
return u.register(c, entities...)
Expand All @@ -81,7 +83,9 @@ func (u *sqlUnit) Register(entities ...interface{}) error {
// Add marks the provided entities as new additions.
func (u *sqlUnit) Add(entities ...interface{}) error {
c := func(t TypeName) bool {
u.mutex.RLock()
_, ok := u.mappers[t]
u.mutex.RUnlock()
return ok
}
return u.add(c, entities...)
Expand All @@ -90,7 +94,9 @@ func (u *sqlUnit) Add(entities ...interface{}) error {
// Alter marks the provided entities as modifications.
func (u *sqlUnit) Alter(entities ...interface{}) error {
c := func(t TypeName) bool {
u.mutex.RLock()
_, ok := u.mappers[t]
u.mutex.RUnlock()
return ok
}
return u.alter(c, entities...)
Expand All @@ -99,7 +105,9 @@ func (u *sqlUnit) Alter(entities ...interface{}) error {
// Remove marks the provided entities as removals.
func (u *sqlUnit) Remove(entities ...interface{}) error {
c := func(t TypeName) bool {
u.mutex.RLock()
_, ok := u.mappers[t]
u.mutex.RUnlock()
return ok
}
return u.remove(c, entities...)
Expand Down
101 changes: 101 additions & 0 deletions v3/sql_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"database/sql"
"errors"
"fmt"
"sync"
"testing"

"github.com/DATA-DOG/go-sqlmock"
Expand Down Expand Up @@ -653,6 +654,31 @@ func (s *SQLUnitTestSuite) TestSQLUnit_Add() {
s.NoError(err)
}

func (s *SQLUnitTestSuite) TestSQLUnit_ConcurrentAdd() {

// arrange.
foo := Foo{ID: 28}
bar := Bar{ID: "28"}

// action.
var err, err2 error
var wg sync.WaitGroup
wg.Add(2)
go func() {
err = s.sut.Add(foo)
wg.Done()
}()
go func() {
err2 = s.sut.Add(bar)
wg.Done()
}()
wg.Wait()

// assert.
s.NoError(err)
s.NoError(err2)
}

func (s *SQLUnitTestSuite) TestSQLUnit_Alter_Empty() {

// arrange.
Expand Down Expand Up @@ -700,6 +726,31 @@ func (s *SQLUnitTestSuite) TestSQLUnit_Alter() {
s.NoError(err)
}

func (s *SQLUnitTestSuite) TestSQLUnit_ConcurrentAlter() {

// arrange.
foo := Foo{ID: 28}
bar := Bar{ID: "28"}

// action.
var err, err2 error
var wg sync.WaitGroup
wg.Add(2)
go func() {
err = s.sut.Alter(foo)
wg.Done()
}()
go func() {
err2 = s.sut.Alter(bar)
wg.Done()
}()
wg.Wait()

// assert.
s.NoError(err)
s.NoError(err2)
}

func (s *SQLUnitTestSuite) TestSQLUnit_Remove_Empty() {

// arrange.
Expand Down Expand Up @@ -747,6 +798,31 @@ func (s *SQLUnitTestSuite) TestSQLUnit_Remove() {
s.NoError(err)
}

func (s *SQLUnitTestSuite) TestSQLUnit_ConcurrentRemove() {

// arrange.
foo := Foo{ID: 28}
bar := Bar{ID: "28"}

// action.
var err, err2 error
var wg sync.WaitGroup
wg.Add(2)
go func() {
err = s.sut.Remove(foo)
wg.Done()
}()
go func() {
err2 = s.sut.Remove(bar)
wg.Done()
}()
wg.Wait()

// assert.
s.NoError(err)
s.NoError(err2)
}

func (s *SQLUnitTestSuite) TestSQLUnit_Register_Empty() {

// arrange.
Expand Down Expand Up @@ -795,6 +871,31 @@ func (s *SQLUnitTestSuite) TestSQLUnit_Register() {
s.NoError(err)
}

func (s *SQLUnitTestSuite) TestSQLUnit_ConcurrentRegister() {

// arrange.
foo := Foo{ID: 28}
bar := Bar{ID: "28"}

// action.
var err, err2 error
var wg sync.WaitGroup
wg.Add(2)
go func() {
err = s.sut.Register(foo)
wg.Done()
}()
go func() {
err2 = s.sut.Register(bar)
wg.Done()
}()
wg.Wait()

// assert.
s.NoError(err)
s.NoError(err2)
}

func (s *SQLUnitTestSuite) TearDownTest() {
s.db.Close()
s.mc.Finish()
Expand Down

0 comments on commit e94b202

Please sign in to comment.