@@ -28,50 +28,84 @@ public async Task Reuse_Session_Before_Creating_new()
2828 [ Fact ]
2929 public async Task Creating_Session_Throw_Exception ( )
3030 {
31- const string errorMessage = "Error on open session" ;
32- const int maxSessionSize = 200 ;
31+ for ( var it = 0 ; it < 100_000 ; it ++ )
32+ {
33+ const string errorMessage = "Error on open session" ;
34+ const int maxSessionSize = 200 ;
35+
36+ var mockPoolingSessionFactory = new MockPoolingSessionFactory
37+ {
38+ Open = sessionNum =>
39+ sessionNum <= maxSessionSize * 2
40+ ? Task . FromException ( new YdbException ( errorMessage ) )
41+ : Task . CompletedTask
42+ } ;
43+
44+ var sessionSource = new PoolingSessionSource < MockPoolingSession > (
45+ mockPoolingSessionFactory , new YdbConnectionStringBuilder { MaxSessionPool = maxSessionSize }
46+ ) ;
47+
48+ var tasks = new List < Task > ( ) ;
49+ var countSuccess = 0 ;
3350
51+ for ( var i = 0 ; i < maxSessionSize * 4 ; i ++ )
52+ {
53+ tasks . Add ( Task . Run ( async ( ) =>
54+ {
55+ try
56+ {
57+ var session = await sessionSource . OpenSession ( ) ;
58+ // ReSharper disable once AccessToModifiedClosure
59+ Interlocked . Increment ( ref countSuccess ) ;
60+ Assert . True ( session . SessionId ( ) > maxSessionSize * 2 ) ;
61+ session . Close ( ) ;
62+ }
63+ catch ( YdbException e )
64+ {
65+ Assert . Equal ( errorMessage , e . Message ) ;
66+ }
67+ } ) ) ;
68+ }
69+
70+ await Task . WhenAll ( tasks ) ;
71+ Assert . Equal ( maxSessionSize * 2 , Volatile . Read ( ref countSuccess ) ) ;
72+ Assert . True ( maxSessionSize * 3 >= mockPoolingSessionFactory . SessionNum ) ;
73+ Assert . True ( maxSessionSize * 2 < mockPoolingSessionFactory . SessionNum ) ;
74+ }
75+ }
76+
77+ [ Fact ]
78+ public async Task HighContention_OpenClose_NotCanceledException ( )
79+ {
3480 var mockPoolingSessionFactory = new MockPoolingSessionFactory
3581 {
36- Open = sessionNum =>
37- sessionNum <= maxSessionSize * 2
38- ? Task . FromException ( new YdbException ( errorMessage ) )
39- : Task . CompletedTask
82+ Open = async _ => await Task . Yield ( )
4083 } ;
84+ const int highContentionTasks = 100 ;
85+ const int maxSessionSize = highContentionTasks / 2 ;
4186
4287 var sessionSource = new PoolingSessionSource < MockPoolingSession > (
4388 mockPoolingSessionFactory , new YdbConnectionStringBuilder { MaxSessionPool = maxSessionSize }
4489 ) ;
4590
46- var tasks = new List < Task > ( ) ;
47- var countSuccess = 0 ;
48-
49- for ( var i = 0 ; i < maxSessionSize * 4 ; i ++ )
91+ for ( var it = 0 ; it < 100_000 ; it ++ )
5092 {
51- tasks . Add ( Task . Run ( async ( ) =>
93+ var tasks = new Task [ highContentionTasks ] ;
94+
95+ for ( var i = 0 ; i < highContentionTasks ; i ++ )
5296 {
53- try
97+ tasks [ i ] = Task . Run ( async ( ) =>
5498 {
5599 var session = await sessionSource . OpenSession ( ) ;
56- // ReSharper disable once AccessToModifiedClosure
57- Interlocked . Increment ( ref countSuccess ) ;
58- Assert . True ( session . SessionId ( ) > maxSessionSize * 2 ) ;
100+ Assert . True ( session . SessionId ( ) <= maxSessionSize ) ;
101+ await Task . Yield ( ) ;
59102 session . Close ( ) ;
60- }
61- catch ( YdbException e )
62- {
63- Assert . Equal ( errorMessage , e . Message ) ;
64- }
65- } ) ) ;
66- }
103+ } ) ;
104+ }
67105
68- await Task . WhenAll ( tasks ) ;
69- Assert . Equal ( maxSessionSize * 2 , Volatile . Read ( ref countSuccess ) ) ;
70- Assert . True ( maxSessionSize * 3 >= mockPoolingSessionFactory . SessionNum ) ;
71- Assert . True ( maxSessionSize * 2 < mockPoolingSessionFactory . SessionNum ) ;
106+ await Task . WhenAll ( tasks ) ;
107+ }
72108 }
73-
74-
75109}
76110
77111internal static class ISessionExtension
0 commit comments