コード例 #1
0
        public Activity ProcessResourceStart(ProcessContext processContext)
        {
            bool result = processContext.IsResourceUpdated(out var infos);

            if (!result)
            {
                _logger.Info("No changes detected on ResourceId=\"{0}\""
                             , processContext.CurrentInfo.ResourceId
                             );
            }
            else
            {
                _logger.Info("({4}/{5}) Detected change on ResourceId=\"{0}\", Resource.ModifiedSource={6},Resource.Modified={1}, OldState.Modified={2}, OldState.Retry={3}. Processing..."
                             , processContext.CurrentInfo.ResourceId
                             , infos.current?.ToString()
                             , infos.last?.ToString()
                             , processContext.LastState?.RetryCount
                             , processContext.Index
                             , processContext.Total
                             , infos.source ?? string.Empty
                             );
            }

            Activity activity = _start("ProcessResource", () => new
            {
                ProcessContext = processContext,
                Tenant         = _tenant,
            });

            return(activity);
        }
コード例 #2
0
        public void ProcessResourceSuccessful(Activity activity, int idx, int total, ProcessContext processContext)
        {
            //_setTags(activity, processType.ToString(), processType.ToString());

            _stop(activity, () => new
            {
                Idx            = idx,
                Total          = total,
                ProcessContext = processContext,
                Tenant         = _tenant,
            }
                  );

            if (processContext.ResultType == ResultType.NoNewData)
            {
                _logger.Info($"({idx}/{total}) ResourceId=\"{processContext.CurrentInfo.ResourceId}\" No payload retrived, so no new state. Generally due to a same-checksum");
            }
            else if (processContext.ResultType == ResultType.NoAction)
            {
                _logger.Info($"({idx}/{total}) ResourceId=\"{processContext.CurrentInfo.ResourceId}\" No action has been triggered and payload has not been retrieved. We do not change the state");
            }
            else if (processContext.ResultType == ResultType.Normal)
            {
                _logger.Info($"({idx}/{total}) ResourceId=\"{processContext.CurrentInfo.ResourceId}\" handled {(processContext.NewState.RetryCount == 0 ? "" : "not ")}successfully {(activity != null ? " in" + (activity.Duration.ToString()) : "")}");
            }
        }
コード例 #3
0
 public void FetchResourceFailed(Activity activity, ProcessContext pc, Exception ex)
 {
     _stop(activity, () => new
     {
         ProcessContext = pc,
         Exception      = ex,
         Tenant         = _tenant,
     }
           );
 }
コード例 #4
0
        public void FetchResourceSuccessful(Activity activity, ProcessContext pc)
        {
            //_setTags(activity, processType.ToString(), processType.ToString());

            _stop(activity, () => new
            {
                ProcessContext = pc,
                Tenant         = _tenant,
            }
                  );
        }
コード例 #5
0
        public Activity FetchResourceStart(ProcessContext pc)
        {
            Activity activity = _start("FetchResource", () => new
            {
                ProcessContext = pc,
                Tenant         = _tenant,
            }
                                       );

            return(activity);
        }
コード例 #6
0
        public void ProcessResourceFailed(Activity activity, ProcessContext pc, bool isBanned, Exception ex)
        {
            var lvl = isBanned ? LogLevel.Fatal : LogLevel.Warn;

            _logger.Log(lvl, ex, $"({pc.Index}/{pc.Total}) ResourceId=\"{pc.CurrentInfo.ResourceId}\" process Failed");

            _stop(activity, () => new
            {
                ProcessContext = pc,
                Exception      = ex,
                Tenant         = _tenant,
            });
        }
コード例 #7
0
ファイル: ResourceWatcher.cs プロジェクト: Thieum/Ark.Tools
        private List <ProcessContext> _createEvalueteList(List <IResourceMetadata> list, IEnumerable <ResourceState> states)
        {
            var ev = list.GroupJoin(states, i => i.ResourceId, s => s.ResourceId, (i, s) =>
            {
                var x = new ProcessContext {
                    CurrentInfo = i, LastState = s.SingleOrDefault()
                };
                if (x.LastState == null)
                {
                    x.ProcessType = ProcessType.New;
                }
                else if (x.LastState.RetryCount == 0 && x.IsResourceUpdated(out _))
                {
                    x.ProcessType = ProcessType.Updated;
                }
                else if (x.LastState.RetryCount > 0 && x.LastState.RetryCount <= _config.MaxRetries)
                {
                    x.ProcessType = ProcessType.Retry;
                }
                else if (x.LastState.RetryCount > _config.MaxRetries &&
                         x.IsResourceUpdated(out _) &&
                         x.LastState.LastEvent + _config.BanDuration < SystemClock.Instance.GetCurrentInstant()
                         // BAN expired and new version
                         )
                {
                    x.ProcessType = ProcessType.RetryAfterBan;
                }
                else if (x.LastState.RetryCount > _config.MaxRetries &&
                         x.IsResourceUpdated(out _) &&
                         !(x.LastState.LastEvent + _config.BanDuration < SystemClock.Instance.GetCurrentInstant())
                         // BAN
                         )
                {
                    x.ProcessType = ProcessType.Banned;
                }
                else
                {
                    x.ProcessType = ProcessType.NothingToDo;
                }

                if (x.ProcessType == ProcessType.NothingToDo || x.ProcessType == ProcessType.Banned)
                {
                    x.ResultType = ResultType.Skipped;
                }

                return(x);
            }).ToList();

            return(ev);
        }
コード例 #8
0
        public void ProcessResourceFailed(Activity activity, int idx, int total, ProcessContext processContext, bool isBanned, Exception ex)
        {
            var lvl = isBanned ? LogLevel.Fatal : LogLevel.Warn;

            _logger.Log(lvl, ex, $"({idx}/{total}) ResourceId=\"{processContext.CurrentInfo.ResourceId}\" process Failed");

            _stop(activity, () => new
            {
                Idx            = idx,
                Total          = total,
                ProcessContext = processContext,
                IsBanned       = isBanned,
                Exception      = ex,
                Tenant         = _tenant,
            }
                  );
        }
コード例 #9
0
ファイル: ResourceWatcher.cs プロジェクト: Thieum/Ark.Tools
        private async Task <T> _fetchResource(ProcessContext pc, CancellationToken ctk = default)
        {
            var info      = pc.CurrentInfo;
            var lastState = pc.LastState;

            var activity = _diagnosticSource.FetchResourceStart(pc);

            try
            {
                var res = await _retrievePayload(info, lastState, ctk);

                _diagnosticSource.FetchResourceSuccessful(activity, pc);
                return(res);
            } catch (Exception ex)
            {
                _diagnosticSource.FetchResourceFailed(activity, pc, ex);
                throw;
            }
        }
コード例 #10
0
        public Activity ProcessResourceStart(ProcessContext processContext)
        {
            _logger.Info("({4}/{5}) Detected change on ResourceId=\"{0}\", Resource.Modified={1}, OldState.Modified={2}, OldState.Retry={3}. Processing..."
                         , processContext.CurrentInfo.ResourceId
                         , processContext.CurrentInfo.Modified
                         , processContext.LastState?.Modified
                         , processContext.LastState?.RetryCount
                         , processContext.Index
                         , processContext.Total
                         );

            Activity activity = _start("ProcessResource", () => new
            {
                ProcessContext = processContext,
                Tenant         = _tenant,
            });

            return(activity);
        }
コード例 #11
0
ファイル: ResourceWatcher.cs プロジェクト: Thieum/Ark.Tools
        private async Task _processEntry(ProcessContext pc, CancellationToken ctk = default)
        {
            var info      = pc.CurrentInfo;
            var lastState = pc.LastState;
            var dataType  = pc.ProcessType;

            try
            {
                var processActivity = _diagnosticSource.ProcessResourceStart(pc);

                AsyncLazy <T> payload = new AsyncLazy <T>(() => _fetchResource(pc, ctk));

                var state = pc.NewState = new ResourceState()
                {
                    Tenant          = _config.Tenant,
                    ResourceId      = info.ResourceId,
                    Modified        = lastState?.Modified ?? default, // we want to update modified only on success or Ban or first run
                    ModifiedSources = lastState?.ModifiedSources,     // we want to update modified multiple only on success or Ban or first run
                    LastEvent       = SystemClock.Instance.GetCurrentInstant(),
                    RetryCount      = lastState?.RetryCount ?? 0,
                    CheckSum        = lastState?.CheckSum,
                    RetrievedAt     = lastState?.RetrievedAt,
                    Extensions      = info.Extensions
                };

                try
                {
                    pc.ResultType = ResultType.Normal;
                    IResourceState newState = default;

                    await _processResource(new ChangedStateContext <T>(info, lastState, payload), ctk).ConfigureAwait(false);

                    // if handlers retrived data, fetch the result to check the checksum
                    if (payload.IsStarted)
                    {
                        // if the retrievePayload task gone in exception but the _processResource did not ...
                        // here we care only if we have a payload to use
                        if (payload.Task.Status == TaskStatus.RanToCompletion)
                        {
                            newState = await payload;

                            if (newState != null)
                            {
                                if (!string.IsNullOrWhiteSpace(newState.CheckSum) && state.CheckSum != newState.CheckSum)
                                {
                                    _logger.Info("Checksum changed on ResourceId=\"{0}\" from \"{1}\" to \"{2}\"", state.ResourceId, state.CheckSum, newState.CheckSum);
                                }

                                state.CheckSum    = newState.CheckSum;
                                state.RetrievedAt = newState.RetrievedAt;

                                pc.ResultType = ResultType.Normal;
                            }
                            else // no payload retrived, so no new state. Generally due to a same-checksum
                            {
                                pc.ResultType = ResultType.NoNewData;
                            }

                            state.Extensions      = info.Extensions;
                            state.Modified        = info.Modified;
                            state.ModifiedSources = info.ModifiedSources;
                            state.RetryCount      = 0; // success
                        }
                        else
                        {
                            throw new NotSupportedException($"({pc.Index}/{pc.Total}) ResourceId=\"{state.ResourceId}\" we cannot reach this point!");
                        }
                    }
                    else // for some reason, no action has been and payload has not been retrieved. We do not change the state
                    {
                        pc.ResultType = ResultType.NoAction;
                    }

                    _diagnosticSource.ProcessResourceSuccessful(processActivity, pc);

                    if (processActivity.Duration > _config.ResourceDurationNotificationLimit)
                    {
                        _diagnosticSource.ProcessResourceTookTooLong(info.ResourceId, processActivity);
                    }
                }
                catch (Exception ex)
                {
                    state.LastException = ex;
                    pc.ResultType       = ResultType.Error;
                    var isBanned = ++state.RetryCount == _config.MaxRetries;

                    state.Extensions = info.Extensions;

                    _diagnosticSource.ProcessResourceFailed(processActivity, pc, isBanned, ex);
                }

                await _stateProvider.SaveStateAsync(new[] { state }, ctk).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                // chomp it, we'll retry this file next time, forever, fuckit
                pc.ResultType = ResultType.Error;
                _diagnosticSource.ProcessResourceSaveFailed(info.ResourceId, ex);
            }
        }
コード例 #12
0
 public virtual void OnProcessResourceStop(string tenant, int idx, int total, ProcessContext processContext, bool isBanned, Exception exception)
 {
 }
コード例 #13
0
 public virtual void OnProcessResourceStop(string tenant, ProcessContext processContext, Exception exception)
 {
 }