-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Description
When poolInstance is shared in multiple go routines, object may be reused before cleaned, cleaned before reused or so.
package tests
import (
"fmt"
"sync"
"testing"
"time"
"github.com/AlexsanderHamir/GenPool/pool"
)
type Data struct {
Stage string
pool.Fields[Data]
}
var poolInstance *pool.ShardedPool[Data, *Data]
func SetupPool() {
var err error
// PersistOrderUpdate
{
allocator := func() *Data {
return &Data{
Stage: "new",
}
}
cleanupPolicy := pool.CleanupPolicy{
Enabled: true,
Interval: 1 * time.Minute,
MinUsageCount: 20,
}
cleaner := func(obj *Data) {
if obj != nil {
if obj.Stage != "used" {
panic("cleaner received an obj.Stage != used: " + obj.Stage)
}
obj.Stage = "reset"
} else {
panic("cleaner received a nil obj")
}
}
config := pool.Config[Data, *Data]{
Cleanup: cleanupPolicy,
Allocator: allocator,
Cleaner: cleaner,
}
poolInstance, err = pool.NewPoolWithConfig(config)
if err != nil {
return
}
}
}
func TestThreadSafety(t *testing.T) {
SetupPool()
v := make(chan *Data, 100)
// pool consumer
go func() {
for {
obj := poolInstance.Get()
if obj.Stage != "new" && obj.Stage != "reset" {
// got a used obj that should be cleared before
fmt.Println("got an obj.Stage != new && obj.Stage != reset: " + obj.Stage)
//panic("got an obj.Stage != new && obj.Stage != reset: " + obj.Stage)
}
obj.Stage = "used"
v <- obj
}
}()
// put it back
go func() {
for {
obj := <-v
if obj.Stage != "used" {
fmt.Println("returning an obj.Stage != used: " + obj.Stage)
//panic("returning an obj.Stage != used: " + obj.Stage)
}
poolInstance.Put(obj)
}
}()
select {}
}
func TestThreadSafety2(t *testing.T) {
SetupPool()
v := make(chan *Data, 100)
mu := sync.Mutex{}
// pool consumer
go func() {
for {
mu.Lock()
obj := poolInstance.Get()
mu.Unlock()
if obj.Stage != "new" && obj.Stage != "reset" {
// got a used obj that should be cleared before
fmt.Println("got an obj.Stage != new && obj.Stage != reset: " + obj.Stage)
//panic("got an obj.Stage != new && obj.Stage != reset: " + obj.Stage)
}
obj.Stage = "used"
v <- obj
}
}()
// put it back
go func() {
for {
obj := <-v
if obj.Stage != "used" {
fmt.Println("returning an obj.Stage != used: " + obj.Stage)
//panic("returning an obj.Stage != used: " + obj.Stage)
}
mu.Lock()
poolInstance.Put(obj)
mu.Unlock()
}
}()
select {}
}
Metadata
Metadata
Assignees
Labels
No labels