Пример #1
0
    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);
        }
    }
Пример #2
0
    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);
    }
Пример #3
0
    // 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);
        }
    }