/// <summary> /// Creates and runs a distributed cache service /// </summary> /// <exception cref="CacheException">thrown when cache startup fails</exception> public static async Task RunAsync(DistributedCacheServiceArguments arguments) { // Switching to another thread. await Task.Yield(); var host = arguments.Host; var logger = arguments.Logger; var factory = new CacheServerFactory(arguments); await host.OnStartingServiceAsync(); var eitherServer = factory.Create(); using (var server = ((StartupShutdownBase)eitherServer.cacheServer) ?? eitherServer.contentServer) { var context = new Context(logger); try { var startupResult = await server.StartupAsync(context); if (!startupResult) { throw new CacheException(startupResult.ToString()); } host.OnStartedService(); logger.Info("Service started"); await arguments.Cancellation.WaitForCancellationAsync(); logger.Always("Exit event set"); } finally { var timeoutInMinutes = arguments?.Configuration?.DistributedContentSettings?.MaxShutdownDurationInMinutes ?? 30; BoolResult result = await ShutdownWithTimeoutAsync(context, server, TimeSpan.FromMinutes(timeoutInMinutes)); if (!result) { logger.Warning("Failed to shutdown local content server: {0}", result); } host.OnTeardownCompleted(); } } }
/// <summary> /// Creates and runs a distributed cache service /// </summary> /// <exception cref="CacheException">thrown when cache startup fails</exception> public static async Task RunAsync(DistributedCacheServiceArguments arguments) { // Switching to another thread. await Task.Yield(); var host = arguments.Host; var timer = Stopwatch.StartNew(); InitializeGlobalLifetimeManager(host); // NOTE(jubayard): this is the entry point for running CASaaS. At this point, the Logger inside the // arguments holds the client's implementation of our logging interface ILogger. Here, we may override the // client's decision with our own. // The disposableToken helps ensure that we shutdown properly and all logs are sent to their final // destination. var loggerReplacement = CreateReplacementLogger(arguments); arguments.Logger = loggerReplacement.Logger; using var disposableToken = loggerReplacement.DisposableToken; AdjustCopyInfrastructure(arguments); var context = new Context(arguments.Logger); await ReportStartingServiceAsync(context, host); var factory = new CacheServerFactory(arguments); var operationContext = new OperationContext(context); ServiceOfflineDurationTracker serviceRunningTracker = null; // Technically, this method doesn't own the file copier, but no one actually owns it. // So to clean up the resources (and print some stats) we dispose it here. using (arguments.Copier as IDisposable) using (var server = factory.Create()) { try { var startupResult = await server.StartupAsync(context); if (!startupResult) { throw new CacheException(startupResult.ToString()); } var serviceRunningTrackerResult = ServiceOfflineDurationTracker.Create( operationContext, SystemClock.Instance, new PassThroughFileSystem(), arguments.Configuration); ReportServiceStarted(operationContext, host, serviceRunningTrackerResult, timer.Elapsed); serviceRunningTracker = serviceRunningTrackerResult.GetValueOrDefault(); await arguments.Cancellation.WaitForCancellationAsync(); ReportShuttingDownService(context); } catch (Exception e) { ReportServiceStartupFailed(context, e, timer.Elapsed); throw; } finally { // Writing the current time before shutting the service down. serviceRunningTracker?.LogCurrentTimeStampToFile(operationContext); timer.Reset(); var timeoutInMinutes = arguments.Configuration?.DistributedContentSettings?.MaxShutdownDurationInMinutes ?? 30; var result = await server .ShutdownAsync(context) .WithTimeoutAsync("Server shutdown", TimeSpan.FromMinutes(timeoutInMinutes)); serviceRunningTracker?.Dispose(); ReportServiceStopped(context, host, result, timer.Elapsed); } } }
/// <summary> /// Creates and runs a distributed cache service /// </summary> /// <exception cref="CacheException">thrown when cache startup fails</exception> public static async Task RunAsync(DistributedCacheServiceArguments arguments) { // Switching to another thread. await Task.Yield(); var host = arguments.Host; var startUpTime = Stopwatch.StartNew(); // NOTE(jubayard): this is the entry point for running CASaaS. At this point, the Logger inside the // arguments holds the client's implementation of our logging interface ILogger. Here, we may override the // client's decision with our own. // The disposableToken helps ensure that we shutdown properly and all logs are sent to their final // destination. var loggerReplacement = CreateReplacementLogger(arguments); arguments.Logger = loggerReplacement.Logger; using var disposableToken = loggerReplacement.DisposableToken; if (arguments.BuildCopyInfrastructure != null) { var(copier, pathTransformer, copyRequester) = arguments.BuildCopyInfrastructure(arguments.Logger); arguments.Copier = copier; arguments.PathTransformer = pathTransformer; arguments.CopyRequester = copyRequester; } var logger = arguments.Logger; var factory = new CacheServerFactory(arguments); await host.OnStartingServiceAsync(); // Technically, this method doesn't own the file copier, but no one actually owns it. // So to clean up the resources (and print some stats) we dispose it here. using (arguments.Copier as IDisposable) using (var server = factory.Create()) { var context = new Context(logger); var ctx = new OperationContext(context); try { var startupResult = await server.StartupAsync(context); if (!startupResult) { throw new CacheException(startupResult.ToString()); } host.OnStartedService(); using var serviceRunningTracker = DistributedCacheServiceRunningTracker.Create( ctx, SystemClock.Instance, new PassThroughFileSystem(), arguments.Configuration, startUpTime.Elapsed).GetValueOrDefault(); await arguments.Cancellation.WaitForCancellationAsync(); context.Always("Exit event set"); } finally { var timeoutInMinutes = arguments?.Configuration?.DistributedContentSettings?.MaxShutdownDurationInMinutes ?? 30; BoolResult result = await ShutdownWithTimeoutAsync(context, server, TimeSpan.FromMinutes(timeoutInMinutes)); if (!result) { context.Warning($"Failed to shutdown local content server: {result}"); } host.OnTeardownCompleted(); } } }
/// <summary> /// Creates and runs a distributed cache service /// </summary> /// <exception cref="CacheException">thrown when cache startup fails</exception> public static async Task RunAsync(DistributedCacheServiceArguments arguments) { // Switching to another thread. await Task.Yield(); var host = arguments.Host; var timer = Stopwatch.StartNew(); InitializeLifetimeTracker(host); using var cts = CancellationTokenSource.CreateLinkedTokenSource(arguments.Cancellation); arguments.Cancellation = cts.Token; if (arguments.Configuration.RespectRequestTeardown) { LifetimeManager.OnTeardownRequested += _ => { cts.Cancel(); }; } // NOTE(jubayard): this is the entry point for running CASaaS. At this point, the Logger inside the // arguments holds the client's implementation of our logging interface ILogger. Here, we may override the // client's decision with our own. // The disposableToken helps ensure that we shutdown properly and all logs are sent to their final // destination. var loggerReplacement = LoggerFactory.CreateReplacementLogger(arguments); arguments.Logger = loggerReplacement.Logger; using var disposableToken = loggerReplacement.DisposableToken; var context = new Context(arguments.Logger); var operationContext = new OperationContext(context, arguments.Cancellation); InitializeActivityTrackerIfNeeded(context, arguments.Configuration.DistributedContentSettings); AdjustCopyInfrastructure(arguments); await ReportStartingServiceAsync(operationContext, host, arguments.Configuration); var factory = new CacheServerFactory(arguments); // Technically, this method doesn't own the file copier, but no one actually owns it. // So to clean up the resources (and print some stats) we dispose it here. using (arguments.Copier as IDisposable) using (var server = factory.Create()) { try { var startupResult = await server.StartupAsync(context); if (!startupResult) { throw new CacheException(startupResult.ToString()); } ReportServiceStarted(operationContext, host); await arguments.Cancellation.WaitForCancellationAsync(); await ReportShuttingDownServiceAsync(operationContext, host); } catch (Exception e) { ReportServiceStartupFailed(context, e, timer.Elapsed); throw; } finally { var timeoutInMinutes = arguments.Configuration?.DistributedContentSettings?.MaxShutdownDurationInMinutes ?? 30; var result = await server .ShutdownAsync(context) .WithTimeoutAsync("Server shutdown", TimeSpan.FromMinutes(timeoutInMinutes)); ReportServiceStopped(context, host, result); } } }