1- // Copyright (C) 2009-2020 Xtensive LLC.
1+ // Copyright (C) 2009-2021 Xtensive LLC.
22// This code is distributed under MIT license terms.
33// See the License.txt file in the project root for more information.
44// Created by: Denis Krjuchkov
@@ -39,7 +39,13 @@ public override void Open()
3939 base . Open ( ) ;
4040 }
4141 else {
42- OpenWithCheckFast ( DefaultCheckConnectionQuery ) ;
42+ var connectionHandlers = Extensions . Get < ConnectionHandlersExtension > ( ) ;
43+ if ( connectionHandlers == null ) {
44+ OpenWithCheckFast ( DefaultCheckConnectionQuery ) ;
45+ }
46+ else {
47+ OpenWithCheckAndNotifications ( DefaultCheckConnectionQuery , connectionHandlers ) ;
48+ }
4349 }
4450 }
4551
@@ -51,7 +57,13 @@ public override Task OpenAsync(CancellationToken cancellationToken)
5157 return base . OpenAsync ( cancellationToken ) ;
5258 }
5359
54- return OpenWithCheckAsync ( DefaultCheckConnectionQuery , cancellationToken ) ;
60+ var connectionHandlers = Extensions . Get < ConnectionHandlersExtension > ( ) ;
61+ if ( connectionHandlers == null ) {
62+ return OpenWithCheckFastAsync ( DefaultCheckConnectionQuery , cancellationToken ) ;
63+ }
64+ else {
65+ return OpenWithCheckAndNotificationsAsync ( DefaultCheckConnectionQuery , connectionHandlers , cancellationToken ) ;
66+ }
5567 }
5668
5769 /// <inheritdoc/>
@@ -66,10 +78,12 @@ public override void OpenAndInitialize(string initializationScript)
6678 ? DefaultCheckConnectionQuery
6779 : initializationScript ;
6880 var connectionHandlers = Extensions . Get < ConnectionHandlersExtension > ( ) ;
69- if ( connectionHandlers == null )
81+ if ( connectionHandlers == null ) {
7082 OpenWithCheckFast ( script ) ;
71- else
72- OpenWithChecksAndNotifications ( script , connectionHandlers ) ;
83+ }
84+ else {
85+ OpenWithCheckAndNotifications ( script , connectionHandlers ) ;
86+ }
7387 }
7488
7589 /// <inheritdoc/>
@@ -82,7 +96,10 @@ public override Task OpenAndInitializeAsync(string initializationScript, Cancell
8296 var script = string . IsNullOrEmpty ( initializationScript . Trim ( ) )
8397 ? DefaultCheckConnectionQuery
8498 : initializationScript ;
85- return OpenWithCheckAsync ( script , token ) ;
99+ var connectionHandlers = Extensions . Get < ConnectionHandlersExtension > ( ) ;
100+ return connectionHandlers == null
101+ ? OpenWithCheckFastAsync ( script , token )
102+ : OpenWithCheckAndNotificationsAsync ( script , connectionHandlers , token ) ;
86103 }
87104
88105 /// <inheritdoc/>
@@ -203,7 +220,7 @@ private void OpenWithCheckFast(string checkQueryString)
203220 var connectionChecked = false ;
204221 var restoreTriggered = false ;
205222 while ( ! connectionChecked ) {
206- base . Open ( ) ;
223+ underlyingConnection . Open ( ) ;
207224 try {
208225 using ( var command = underlyingConnection . CreateCommand ( ) ) {
209226 command . CommandText = checkQueryString ;
@@ -234,15 +251,14 @@ private void OpenWithCheckFast(string checkQueryString)
234251 }
235252 }
236253
237- private void OpenWithChecksAndNotifications ( string checkQueryString , ConnectionHandlersExtension connectionHandlers )
254+ private void OpenWithCheckAndNotifications ( string checkQueryString , ConnectionHandlersExtension connectionHandlers )
238255 {
239256 var connectionChecked = false ;
240257 var restoreTriggered = false ;
241258 var handlers = connectionHandlers . Handlers ;
242259 while ( ! connectionChecked ) {
243260 SqlHelper . NotifyConnectionOpening ( handlers , UnderlyingConnection , ( ! connectionChecked && ! restoreTriggered ) ) ;
244261 underlyingConnection . Open ( ) ;
245- //base.Open();
246262 try {
247263 SqlHelper . NotifyConnectionInitializing ( handlers , UnderlyingConnection , checkQueryString , ( ! connectionChecked && ! restoreTriggered ) ) ;
248264 using ( var command = underlyingConnection . CreateCommand ( ) ) {
@@ -276,24 +292,78 @@ private void OpenWithChecksAndNotifications(string checkQueryString, ConnectionH
276292 }
277293 }
278294
295+ private async Task OpenWithCheckFastAsync ( string checkQueryString , CancellationToken cancellationToken )
296+ {
297+ var connectionChecked = false ;
298+ var restoreTriggered = false ;
299+
300+ while ( ! connectionChecked ) {
301+ cancellationToken . ThrowIfCancellationRequested ( ) ;
302+ await underlyingConnection . OpenAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
303+ try {
304+ var command = underlyingConnection . CreateCommand ( ) ;
305+ await using ( command . ConfigureAwait ( false ) ) {
306+ command . CommandText = checkQueryString ;
307+ _ = await command . ExecuteNonQueryAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
308+ }
309+ connectionChecked = true ;
310+ }
311+ catch ( Exception exception ) {
312+ if ( InternalHelpers . ShouldRetryOn ( exception ) ) {
313+ if ( restoreTriggered ) {
314+ throw ;
315+ }
316+ var newConnection = new SqlServerConnection ( underlyingConnection . ConnectionString ) ;
317+ try {
318+ underlyingConnection . Close ( ) ;
319+ underlyingConnection . Dispose ( ) ;
320+ }
321+ catch { }
322+
323+ underlyingConnection = newConnection ;
324+ restoreTriggered = true ;
325+ continue ;
326+ }
327+
328+ throw ;
329+ }
330+ }
331+ }
279332
280- private async Task OpenWithCheckAsync ( string checkQueryString , CancellationToken cancellationToken )
333+ private async Task OpenWithCheckAndNotificationsAsync ( string checkQueryString ,
334+ ConnectionHandlersExtension connectionHandlers , CancellationToken cancellationToken )
281335 {
282336 var connectionChecked = false ;
283337 var restoreTriggered = false ;
338+ var handlers = connectionHandlers . Handlers ;
284339
285340 while ( ! connectionChecked ) {
286341 cancellationToken . ThrowIfCancellationRequested ( ) ;
287- await base . OpenAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
342+
343+ await SqlHelper . NotifyConnectionOpeningAsync ( handlers ,
344+ UnderlyingConnection , ( ! connectionChecked && ! restoreTriggered ) , cancellationToken )
345+ . ConfigureAwait ( false ) ;
346+
347+ await underlyingConnection . OpenAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
288348 try {
349+ await SqlHelper . NotifyConnectionInitializingAsync ( handlers ,
350+ UnderlyingConnection , checkQueryString , ( ! connectionChecked && ! restoreTriggered ) , cancellationToken )
351+ . ConfigureAwait ( false ) ;
352+
289353 var command = underlyingConnection . CreateCommand ( ) ;
290354 await using ( command . ConfigureAwait ( false ) ) {
291355 command . CommandText = checkQueryString ;
292356 _ = await command . ExecuteNonQueryAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
293357 }
294358 connectionChecked = true ;
359+ await SqlHelper . NotifyConnectionOpenedAsync ( handlers , UnderlyingConnection , ( ! connectionChecked && ! restoreTriggered ) , cancellationToken )
360+ . ConfigureAwait ( false ) ;
295361 }
296362 catch ( Exception exception ) {
363+ await SqlHelper . NotifyConnectionOpeningFailedAsync ( handlers ,
364+ UnderlyingConnection , exception , ( ! connectionChecked && ! restoreTriggered ) , cancellationToken )
365+ . ConfigureAwait ( false ) ;
366+
297367 if ( InternalHelpers . ShouldRetryOn ( exception ) ) {
298368 if ( restoreTriggered ) {
299369 throw ;
0 commit comments