protected override async Task RunInternal(CancellationToken cancellationToken) { var operationName = GetType().GetOperationName(nameof(WakeUp)); while (!cancellationToken.IsCancellationRequested) { var error = default(Exception?); try { using var activity = FusionTrace.StartActivity(operationName); await WakeUp(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { throw; } catch (Exception e) { if (e is ObjectDisposedException ode #if NETSTANDARD2_0 && ode.Message.Contains("'IServiceProvider'")) #else && ode.Message.Contains("'IServiceProvider'", StringComparison.Ordinal)) #endif { // Special case: this exception can be thrown on IoC container disposal, // and if we don't handle it in a special way, DbWakeSleepProcessBase // descendants may flood the log with exceptions till the moment they're stopped. throw; } error = e; Log.LogError(e, "WakeUp failed"); } await Sleep(error, cancellationToken).ConfigureAwait(false); } }
protected virtual Activity?StartActivity(ICommand originalCommand) { var operationName = originalCommand.GetType().GetOperationName("Invalidate"); var activity = FusionTrace.StartActivity(operationName); if (activity != null) { var tags = new ActivityTagsCollection { { "originalCommand", originalCommand.ToString() } }; var activityEvent = new ActivityEvent(operationName, tags: tags); activity.AddEvent(activityEvent); } return(activity); }
// Protected methods protected virtual async Task ProcessBatch(List <BatchItem <TKey, TDbEntity> > batch, CancellationToken cancellationToken) { using var activity = FusionTrace.StartActivity(ProcessBatchOperationName); if (activity != null) { var tags = new ActivityTagsCollection { { "batchSize", batch.Count } }; var activityEvent = new ActivityEvent(ProcessBatchOperationName, tags: tags); activity.AddEvent(activityEvent); } var dbContext = CreateDbContext(); await using var _ = dbContext.ConfigureAwait(false); var keys = new HashSet <TKey>(); foreach (var item in batch) { if (!item.TryCancel(cancellationToken)) { keys.Add(item.Input); } } var pEntity = Expression.Parameter(typeof(TDbEntity), "e"); var eKey = KeyExtractorExpressionBuilder(pEntity); var eBody = Expression.Call(Expression.Constant(keys), ContainsMethod, eKey); var eLambda = (Expression <Func <TDbEntity, bool> >)Expression.Lambda(eBody, pEntity); var query = QueryTransformer(dbContext.Set <TDbEntity>().Where(eLambda)); var entities = await query .ToDictionaryAsync(KeyExtractor, cancellationToken) .ConfigureAwait(false); PostProcessor(entities); foreach (var item in batch) { entities.TryGetValue(item.Input, out var entity); item.SetResult(Result.Value(entity) !, cancellationToken); } }