public static Result <DistributedCacheServiceRunningTracker> Create( OperationContext context, IClock clock, IAbsFileSystem fileSystem, DistributedCacheServiceConfiguration configuration, TimeSpan startUpTime) { return(context.PerformOperation(Tracer, () => { var logIntervalSeconds = configuration.DistributedContentSettings.ServiceRunningLogInSeconds; if (logIntervalSeconds == null) { context.TraceInfo(ServiceStartedTrace(startUpTime)); return new Result <DistributedCacheServiceRunningTracker>($"{nameof(DistributedCacheServiceRunningTracker)} is disabled"); } var logFilePath = configuration.LocalCasSettings.GetCacheRootPathWithScenario(LocalCasServiceSettings.DefaultCacheName) / FileName; var serviceTracker = new DistributedCacheServiceRunningTracker(context, clock, fileSystem, logIntervalSeconds.Value, logFilePath); serviceTracker.Start(context, startUpTime).ThrowIfFailure(); return new Result <DistributedCacheServiceRunningTracker>(serviceTracker); })); }
/// <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(); } } }