11package pool
22
33import (
4- "bytes"
54 "context"
65 "errors"
76 "fmt"
87 "path"
98 "runtime"
10- "runtime/debug"
119 "sync"
1210 "sync/atomic"
1311 "testing"
3533 testItem struct {
3634 v int32
3735
38- closed bytes. Buffer
36+ closed bool
3937
4038 onClose func () error
4139 onIsAlive func () bool
@@ -104,6 +102,10 @@ func (p *testWaitChPool) whenWantWaitCh() <-chan struct{} {
104102func (p * testWaitChPool ) Put (ch * chan * testItem ) {}
105103
106104func (t * testItem ) IsAlive () bool {
105+ if t .closed {
106+ return false
107+ }
108+
107109 if t .onIsAlive != nil {
108110 return t .onIsAlive ()
109111 }
@@ -124,13 +126,9 @@ func (t *testItem) NodeID() uint32 {
124126}
125127
126128func (t * testItem ) Close (context.Context ) error {
127- if t .closed .Len () > 0 {
128- debug .PrintStack ()
129- fmt .Println (t .closed .String ())
130- panic ("item already closed" )
131- }
132-
133- t .closed .Write (debug .Stack ())
129+ defer func () {
130+ t .closed = true
131+ }()
134132
135133 if t .onClose != nil {
136134 return t .onClose ()
@@ -889,6 +887,99 @@ func TestPool(t *testing.T) { //nolint:gocyclo
889887 })
890888 })
891889 t .Run ("With" , func (t * testing.T ) {
890+ t .Run ("ItemFromPoolIsNotAlive" , func (t * testing.T ) {
891+ var (
892+ created atomic.Int32
893+ closed atomic.Int32
894+ nextID atomic.Int32
895+ )
896+ assertCreated := func (exp int32 ) {
897+ if act := created .Load (); act != exp {
898+ t .Errorf (
899+ "unexpected number of created items: %v; want %v" ,
900+ act , exp ,
901+ )
902+ }
903+ }
904+ assertClosed := func (exp int32 ) {
905+ if act := closed .Load (); act != exp {
906+ t .Errorf (
907+ "unexpected number of closed items: %v; want %v" ,
908+ act , exp ,
909+ )
910+ }
911+ }
912+ p := New [* testItem , testItem ](rootCtx ,
913+ WithLimit [* testItem , testItem ](1 ),
914+ WithCreateItemTimeout [* testItem , testItem ](50 * time .Millisecond ),
915+ WithCloseItemTimeout [* testItem , testItem ](50 * time .Millisecond ),
916+ WithCreateItemFunc (func (context.Context ) (* testItem , error ) {
917+ created .Add (1 )
918+ alived := true
919+ v := testItem {
920+ v : nextID .Add (1 ),
921+ onIsAlive : func () bool {
922+ defer func () {
923+ alived = false
924+ }()
925+
926+ return alived
927+ },
928+ onClose : func () error {
929+ closed .Add (1 )
930+
931+ return nil
932+ },
933+ }
934+
935+ return & v , nil
936+ }),
937+ )
938+ defer func () {
939+ _ = p .Close (context .Background ())
940+ }()
941+
942+ s1 := mustGetItem (t , p )
943+ assertClosed (0 )
944+ assertCreated (1 )
945+ require .Len (t , p .index , 1 )
946+
947+ mustPutItem (t , p , s1 )
948+ assertClosed (0 )
949+ assertCreated (1 )
950+ require .Len (t , p .index , 1 )
951+ require .Equal (t , 1 , p .idle .Len ())
952+
953+ s2 , err := p .getItem (context .Background ())
954+ require .NoError (t , err )
955+ assertCreated (2 )
956+ assertClosed (1 )
957+ require .Len (t , p .index , 1 )
958+ require .Equal (t , 0 , p .idle .Len ())
959+
960+ _ , err = p .getItem (context .Background ())
961+ require .ErrorIs (t , err , errPoolIsOverflow )
962+ assertCreated (2 )
963+ assertClosed (1 )
964+ require .Len (t , p .index , 1 )
965+ require .Equal (t , 0 , p .idle .Len ())
966+
967+ require .NoError (t , p .Close (context .Background ()))
968+ assertCreated (2 )
969+ assertClosed (1 )
970+
971+ require .Len (t , p .index , 1 )
972+ require .Equal (t , 0 , p .idle .Len ())
973+
974+ require .ErrorIs (t , p .putItem (context .Background (), s2 ), errClosedPool )
975+ assertClosed (2 )
976+
977+ require .True (t , s2 .closed )
978+ require .False (t , s2 .IsAlive ())
979+
980+ require .Len (t , p .index , 0 )
981+ require .Equal (t , 0 , p .idle .Len ())
982+ })
892983 t .Run ("ExplicitItemClose" , func (t * testing.T ) {
893984 var (
894985 created atomic.Int32
0 commit comments