@@ -35,6 +35,7 @@ internal sealed partial class InsideRuntimeClient : IRuntimeClient, ILifecyclePa
3535 private readonly SharedCallbackData sharedCallbackData ;
3636 private readonly SharedCallbackData systemSharedCallbackData ;
3737 private readonly PeriodicTimer callbackTimer ;
38+ private int _isStopping ;
3839
3940 private GrainLocator grainLocator ;
4041 private MessageCenter messageCenter ;
@@ -44,7 +45,7 @@ internal sealed partial class InsideRuntimeClient : IRuntimeClient, ILifecyclePa
4445 private IGrainCallCancellationManager _cancellationManager ;
4546 private HostedClient hostedClient ;
4647
47- private HostedClient HostedClient => this . hostedClient ??= this . ServiceProvider . GetRequiredService < HostedClient > ( ) ;
48+ private HostedClient HostedClient => this . hostedClient ;
4849 private readonly MessageFactory messageFactory ;
4950 private IGrainReferenceRuntime grainReferenceRuntime ;
5051 private Task callbackTimerTask ;
@@ -110,15 +111,25 @@ public InsideRuntimeClient(
110111
111112 public GrainFactory ConcreteGrainFactory { get ; }
112113
113- private GrainLocator GrainLocator
114- => this . grainLocator ?? ( this . grainLocator = this . ServiceProvider . GetRequiredService < GrainLocator > ( ) ) ;
114+ private GrainLocator GrainLocator => this . grainLocator ;
115115
116- private List < IIncomingGrainCallFilter > GrainCallFilters
117- => this . grainCallFilters ??= new List < IIncomingGrainCallFilter > ( this . ServiceProvider . GetServices < IIncomingGrainCallFilter > ( ) ) ;
116+ private List < IIncomingGrainCallFilter > GrainCallFilters => this . grainCallFilters ;
118117
119- private MessageCenter MessageCenter => this . messageCenter ?? ( this . messageCenter = this . ServiceProvider . GetRequiredService < MessageCenter > ( ) ) ;
118+ private MessageCenter MessageCenter => this . messageCenter ;
120119
121- public IGrainReferenceRuntime GrainReferenceRuntime => this . grainReferenceRuntime ?? ( this . grainReferenceRuntime = this . ServiceProvider . GetRequiredService < IGrainReferenceRuntime > ( ) ) ;
120+ public IGrainReferenceRuntime GrainReferenceRuntime => this . grainReferenceRuntime ;
121+
122+ internal void ConsumeServices ( )
123+ {
124+ this . grainLocator = this . ServiceProvider . GetRequiredService < GrainLocator > ( ) ;
125+ this . grainCallFilters = new List < IIncomingGrainCallFilter > ( this . ServiceProvider . GetServices < IIncomingGrainCallFilter > ( ) ) ;
126+ this . messageCenter = this . ServiceProvider . GetRequiredService < MessageCenter > ( ) ;
127+ this . grainReferenceRuntime = this . ServiceProvider . GetRequiredService < IGrainReferenceRuntime > ( ) ;
128+ this . hostedClient = this . ServiceProvider . GetRequiredService < HostedClient > ( ) ;
129+ _cancellationManager = this . ServiceProvider . GetRequiredService < IGrainCallCancellationManager > ( ) ;
130+ sharedCallbackData . CancellationManager = _cancellationManager ;
131+ systemSharedCallbackData . CancellationManager = _cancellationManager ;
132+ }
122133
123134 public void SendRequest (
124135 GrainReference target ,
@@ -170,18 +181,35 @@ public void SendRequest(
170181 }
171182
172183 var oneWay = ( options & InvokeMethodOptions . OneWay ) != 0 ;
184+ CallbackData callbackData = null ;
173185 if ( ! oneWay )
174186 {
175187 Debug . Assert ( context is not null ) ;
176188
177189 // Register a callback for the request.
178- var callbackData = new CallbackData ( sharedData , context , message , _applicationRequestInstruments ) ;
190+ callbackData = new CallbackData ( sharedData , context , message , _applicationRequestInstruments ) ;
191+ if ( Volatile . Read ( ref _isStopping ) != 0 )
192+ {
193+ callbackData . OnHostShutdown ( ) ;
194+ return ;
195+ }
196+
179197 callbacks . TryAdd ( message . Id , callbackData ) ;
180198 callbackData . SubscribeForCancellation ( cancellationToken ) ;
181199 }
182200 else
183201 {
184202 context ? . Complete ( ) ;
203+ if ( Volatile . Read ( ref _isStopping ) != 0 )
204+ {
205+ return ;
206+ }
207+ }
208+
209+ if ( Volatile . Read ( ref _isStopping ) != 0 )
210+ {
211+ callbackData ? . OnHostShutdown ( ) ;
212+ return ;
185213 }
186214
187215 this . messagingTrace . OnSendRequest ( message ) ;
@@ -497,18 +525,31 @@ public void DeleteObjectReference(IAddressable obj)
497525
498526 private async Task OnRuntimeInitializeStop ( CancellationToken tc )
499527 {
500- foreach ( var ( _, callback ) in callbacks )
501- {
502- callback . OnHostShutdown ( ) ;
503- }
504-
528+ Volatile . Write ( ref _isStopping , 1 ) ;
505529 this . callbackTimer . Dispose ( ) ;
530+ BreakOutstandingMessages ( ) ;
531+
506532 if ( this . callbackTimerTask is { } task )
507533 {
508534 await task . WaitAsync ( tc ) ;
509535 }
510536 }
511537
538+ private void BreakOutstandingMessages ( )
539+ {
540+ foreach ( var ( _, callback ) in callbacks )
541+ {
542+ try
543+ {
544+ callback . OnHostShutdown ( ) ;
545+ }
546+ catch ( Exception exception )
547+ {
548+ LogWarningWhileProcessingCallbackExpiry ( this . logger , exception ) ;
549+ }
550+ }
551+ }
552+
512553 private Task OnRuntimeInitializeStart ( CancellationToken tc )
513554 {
514555 var stopWatch = ValueStopwatch . StartNew ( ) ;
@@ -541,9 +582,7 @@ public void BreakOutstandingMessagesToSilo(SiloAddress deadSilo)
541582
542583 public void Participate ( ISiloLifecycle lifecycle )
543584 {
544- _cancellationManager = this . ServiceProvider . GetRequiredService < IGrainCallCancellationManager > ( ) ;
545- sharedCallbackData . CancellationManager = _cancellationManager ;
546- systemSharedCallbackData . CancellationManager = _cancellationManager ;
585+ ConsumeServices ( ) ;
547586 lifecycle . Subscribe < InsideRuntimeClient > ( ServiceLifecycleStage . RuntimeInitialize , OnRuntimeInitializeStart , OnRuntimeInitializeStop ) ;
548587 }
549588
0 commit comments