@@ -834,6 +834,134 @@ func TestConnection(t *testing.T) {
834
834
t .Errorf ("LocalAddresses do not match. got %v; want %v" , got , want )
835
835
}
836
836
})
837
+
838
+ t .Run ("pinning" , func (t * testing.T ) {
839
+ makeMultipleConnections := func (t * testing.T , numConns int ) (* pool , []* Connection ) {
840
+ t .Helper ()
841
+
842
+ addr := address .Address ("" )
843
+ pool , err := newPool (poolConfig {Address : addr })
844
+ assert .Nil (t , err , "newPool error: %v" , err )
845
+
846
+ err = pool .sem .Acquire (context .Background (), int64 (numConns ))
847
+ assert .Nil (t , err , "error acquiring semaphore: %v" , err )
848
+
849
+ conns := make ([]* Connection , 0 , numConns )
850
+ for i := 0 ; i < numConns ; i ++ {
851
+ conn , err := newConnection (addr )
852
+ assert .Nil (t , err , "newConnection error: %v" , err )
853
+ conn .pool = pool
854
+ conns = append (conns , & Connection {connection : conn })
855
+ }
856
+ return pool , conns
857
+ }
858
+ makeOneConnection := func (t * testing.T ) (* pool , * Connection ) {
859
+ t .Helper ()
860
+
861
+ pool , conns := makeMultipleConnections (t , 1 )
862
+ return pool , conns [0 ]
863
+ }
864
+
865
+ assertPoolPinnedStats := func (t * testing.T , p * pool , cursorConns , txnConns uint64 ) {
866
+ t .Helper ()
867
+
868
+ assert .Equal (t , cursorConns , p .pinnedCursorConnections , "expected %d connections to be pinned to cursors, got %d" ,
869
+ cursorConns , p .pinnedCursorConnections )
870
+ assert .Equal (t , txnConns , p .pinnedTransactionConnections , "expected %d connections to be pinned to transactions, got %d" ,
871
+ txnConns , p .pinnedTransactionConnections )
872
+ }
873
+
874
+ t .Run ("cursors" , func (t * testing.T ) {
875
+ pool , conn := makeOneConnection (t )
876
+ err := conn .PinToCursor ()
877
+ assert .Nil (t , err , "PinToCursor error: %v" , err )
878
+ assertPoolPinnedStats (t , pool , 1 , 0 )
879
+
880
+ err = conn .UnpinFromCursor ()
881
+ assert .Nil (t , err , "UnpinFromCursor error: %v" , err )
882
+
883
+ err = conn .Close ()
884
+ assert .Nil (t , err , "Close error: %v" , err )
885
+ assertPoolPinnedStats (t , pool , 0 , 0 )
886
+ })
887
+ t .Run ("transactions" , func (t * testing.T ) {
888
+ pool , conn := makeOneConnection (t )
889
+ err := conn .PinToTransaction ()
890
+ assert .Nil (t , err , "PinToTransaction error: %v" , err )
891
+ assertPoolPinnedStats (t , pool , 0 , 1 )
892
+
893
+ err = conn .UnpinFromTransaction ()
894
+ assert .Nil (t , err , "UnpinFromTransaction error: %v" , err )
895
+
896
+ err = conn .Close ()
897
+ assert .Nil (t , err , "Close error: %v" , err )
898
+ assertPoolPinnedStats (t , pool , 0 , 0 )
899
+ })
900
+ t .Run ("pool is only updated for first reference" , func (t * testing.T ) {
901
+ pool , conn := makeOneConnection (t )
902
+ err := conn .PinToTransaction ()
903
+ assert .Nil (t , err , "PinToTransaction error: %v" , err )
904
+ assertPoolPinnedStats (t , pool , 0 , 1 )
905
+
906
+ err = conn .PinToCursor ()
907
+ assert .Nil (t , err , "PinToCursor error: %v" , err )
908
+ assertPoolPinnedStats (t , pool , 0 , 1 )
909
+
910
+ err = conn .UnpinFromCursor ()
911
+ assert .Nil (t , err , "UnpinFromCursor error: %v" , err )
912
+ assertPoolPinnedStats (t , pool , 0 , 1 )
913
+
914
+ err = conn .UnpinFromTransaction ()
915
+ assert .Nil (t , err , "UnpinFromTransaction error: %v" , err )
916
+ assertPoolPinnedStats (t , pool , 0 , 1 )
917
+
918
+ err = conn .Close ()
919
+ assert .Nil (t , err , "Close error: %v" , err )
920
+ assertPoolPinnedStats (t , pool , 0 , 0 )
921
+ })
922
+ t .Run ("multiple connections from a pool" , func (t * testing.T ) {
923
+ pool , conns := makeMultipleConnections (t , 2 )
924
+ first , second := conns [0 ], conns [1 ]
925
+
926
+ err := first .PinToTransaction ()
927
+ assert .Nil (t , err , "PinToTransaction error: %v" , err )
928
+ err = second .PinToCursor ()
929
+ assert .Nil (t , err , "PinToCursor error: %v" , err )
930
+ assertPoolPinnedStats (t , pool , 1 , 1 )
931
+
932
+ err = first .UnpinFromTransaction ()
933
+ assert .Nil (t , err , "UnpinFromTransaction error: %v" , err )
934
+ err = first .Close ()
935
+ assert .Nil (t , err , "Close error: %v" , err )
936
+ assertPoolPinnedStats (t , pool , 1 , 0 )
937
+
938
+ err = second .UnpinFromCursor ()
939
+ assert .Nil (t , err , "UnpinFromCursor error: %v" , err )
940
+ err = second .Close ()
941
+ assert .Nil (t , err , "Close error: %v" , err )
942
+ assertPoolPinnedStats (t , pool , 0 , 0 )
943
+ })
944
+ t .Run ("close is ignored if connection is pinned" , func (t * testing.T ) {
945
+ pool , conn := makeOneConnection (t )
946
+ err := conn .PinToCursor ()
947
+ assert .Nil (t , err , "PinToCursor error: %v" , err )
948
+
949
+ err = conn .Close ()
950
+ assert .Nil (t , err , "Close error" )
951
+ assert .NotNil (t , conn .connection , "expected connection to be pinned but it was released to the pool" )
952
+ assertPoolPinnedStats (t , pool , 1 , 0 )
953
+ })
954
+ t .Run ("expire forcefully returns connection to pool" , func (t * testing.T ) {
955
+ pool , conn := makeOneConnection (t )
956
+ err := conn .PinToCursor ()
957
+ assert .Nil (t , err , "PinToCursor error: %v" , err )
958
+
959
+ err = conn .Expire ()
960
+ assert .Nil (t , err , "Expire error" )
961
+ assert .Nil (t , conn .connection , "expected connection to be released to the pool but was not" )
962
+ assertPoolPinnedStats (t , pool , 0 , 0 )
963
+ })
964
+ })
837
965
})
838
966
}
839
967
0 commit comments