Пример #1
0
        private async Task <T> UpdateAsync(bool force)
        {
            PollStatus = "UpdateAsync";
            if (!force && !IsStale)
            {
                return(Data);
            }

            Interlocked.Increment(ref PollingEngine._activePolls);
            PollStatus = "Awaiting Semaphore";
            await _pollSemaphoreSlim.WaitAsync();

            bool errored = false;

            try
            {
                if (!force && !IsStale)
                {
                    return(Data);
                }
                if (_isPolling)
                {
                    return(Data);
                }
                CurrentPollDuration = Stopwatch.StartNew();
                _isPolling          = true;
                PollStatus          = "UpdateCache";
                await _updateFunc();

                PollStatus = "UpdateCache Complete";
                Interlocked.Increment(ref _pollsTotal);
                if (DataTask != null)
                {
                    Interlocked.Increment(ref _pollsSuccessful);
                }
            }
            catch (Exception e)
            {
                var errorMessage = e.Message;
                if (e.InnerException != null)
                {
                    errorMessage += "\n" + e.InnerException.Message;
                }
                SetFail(e, errorMessage);
                errored = true;
            }
            finally
            {
                if (CurrentPollDuration != null)
                {
                    CurrentPollDuration.Stop();
                    LastPollDuration = CurrentPollDuration.Elapsed;
                }
                CurrentPollDuration = null;
                _isPolling          = false;
                PollStatus          = errored ? "Failed" : "Completed";
                _pollSemaphoreSlim.Release();
                Interlocked.Decrement(ref PollingEngine._activePolls);
            }
            return(Data);
        }
Пример #2
0
        /// <summary>
        /// Called on a background thread for when this node is ACTUALLY polling
        /// This is not called if we're not due for a poll when the pass runs
        /// </summary>
        private void InnerPollImpl(bool force = false, bool sync = false)
        {
            CurrentPollDuration = Stopwatch.StartNew();
            try
            {
                PollStatus = "InnerPoll Started";
                if (Polling != null)
                {
                    var ps = new PollStartArgs();
                    Polling(this, ps);
                    if (ps.AbortPoll)
                    {
                        return;
                    }
                }

                int toPoll = 0;
                if (sync || FirstPollRun != null)
                {
                    PollStatus = "DataPollers Queueing (Sync)";
                    var tasks = DataPollers
                                .Where(p => force || p.ShouldPoll)
                                .Select(p => p.PollAsync(force))
                                .ToArray <Task>();
                    Task.WaitAll(tasks);
                    PollStatus = "DataPollers Complete (Sync)";
                }
                else
                {
                    PollStatus = "DataPollers Queueing";
                    foreach (var p in DataPollers)
                    {
                        // Cheap checks to eliminate many uncessary task creations
                        if (!force && !p.ShouldPoll)
                        {
                            continue;
                        }
                        // Kick off the poll and don't wait for it to continue;
#pragma warning disable 4014
                        p.PollStatus = "Kicked off by Node";
                        Interlocked.Add(ref _totalCacheQueues, 1);
                        p.PollAsync(force).ContinueWith(t =>
                        {
                            if (t.IsFaulted)
                            {
                                Current.LogException(t.Exception);
                                PollStatus = "Faulted";
                            }
                            else
                            {
                                PollStatus = "Completed";
                            }
                            Interlocked.Add(ref _totalCachePolls, t.Result);
                        }, TaskContinuationOptions.ExecuteSynchronously).ConfigureAwait(false);
                        toPoll++;
#pragma warning restore 4014
                    }
                    PollStatus = toPoll.ToComma() + " DataPollers Started";
                }

                LastPoll = DateTime.UtcNow;
                Polled?.Invoke(this, new PollResultArgs {
                    Queued = toPoll
                });
                if (FirstPollRun != null)
                {
                    FirstPollRun.Set();
                    FirstPollRun = null;
                }

                Interlocked.Increment(ref _totalPolls);
            }
            finally
            {
                CurrentPollDuration.Stop();
                LastPollDuration    = CurrentPollDuration.Elapsed;
                _isPolling          = false;
                CurrentPollDuration = null;
                PollStatus          = "InnerPoll Complete";
            }
        }
Пример #3
0
        public virtual async Task PollAsync(bool force = false)
        {
            using (MiniProfiler.Current.Step("Poll - " + UniqueKey))
            {
                // If not forced, perform our "should-run" checks
                if (!force && !NeedsPoll)
                {
                    return;
                }

                // Prevent multiple poll threads for this node from running at once
                if (Interlocked.CompareExchange(ref _isPolling, 1, 0) != 0)
                {
                    // We're already running, abort!'
                    // TODO: Date check for sanity and restart?
                    return;
                }

                PollStatus          = "Poll Started";
                CurrentPollDuration = Stopwatch.StartNew();
                try
                {
                    PollStatus = "InnerPoll Started";
                    if (Polling != null)
                    {
                        var ps = new PollStartArgs();
                        Polling(this, ps);
                        if (ps.AbortPoll)
                        {
                            return;
                        }
                    }

                    PollStatus = "DataPollers Queueing";
                    var tasks = new List <Task>();
                    foreach (var p in DataPollers)
                    {
                        if (force || p.ShouldPoll)
                        {
                            tasks.Add(p.PollGenericAsync(force));
                        }
                    }

                    // Hop out early, run nothing else
                    if (tasks.Count == 0)
                    {
                        PollStatus = "DataPollers Complete (None to run)";
                        return;
                    }

                    PollStatus = "DataPollers Queued (Now awaiting)";
                    // Await all children (this itself will be a background fire and forget if desired
                    await Task.WhenAll(tasks).ConfigureAwait(false);

                    PollStatus = "DataPollers Complete (Awaited)";

                    LastPoll = DateTime.UtcNow;
                    Polled?.Invoke(this, new PollResultArgs());
                    Interlocked.Increment(ref _totalPolls);
                }
                finally
                {
                    Interlocked.Exchange(ref _isPolling, 0);
                    if (CurrentPollDuration != null)
                    {
                        CurrentPollDuration.Stop();
                        LastPollDuration = CurrentPollDuration.Elapsed;
                    }
                    CurrentPollDuration = null;
                }
                PollStatus = "Poll Complete";
            }
        }
Пример #4
0
        private async Task <int> UpdateAsync()
        {
            PollStatus = "UpdateAsync";
            if (!_needsPoll && !IsStale)
            {
                return(0);
            }

            PollStatus = "Awaiting Semaphore";
            await _pollSemaphoreSlim.WaitAsync().ConfigureAwait(false);

            bool errored = false;

            try
            {
                if (!_needsPoll && !IsStale)
                {
                    return(0);
                }
                if (_isPolling)
                {
                    return(0);
                }
                CurrentPollDuration = Stopwatch.StartNew();
                _isPolling          = true;
                Interlocked.Increment(ref _pollsTotal);
                PollStatus = "UpdateCache";
                await UpdateCache(this).ConfigureAwait(false);

                PollStatus = "UpdateCache Complete";
                _needsPoll = false;
                if (DataBacker != null)
                {
                    Interlocked.Increment(ref _pollsSuccessful);
                }
                return(DataBacker != null ? 1 : 0);
            }
            catch (Exception e)
            {
                var errorMessage = e.Message;
                if (e.InnerException != null)
                {
                    errorMessage += "\n" + e.InnerException.Message;
                }
                SetFail(errorMessage);
                errored = true;
                return(0);
            }
            finally
            {
                if (CurrentPollDuration != null)
                {
                    CurrentPollDuration.Stop();
                    LastPollDuration = CurrentPollDuration.Elapsed;
                }
                CurrentPollDuration = null;
                _isPolling          = false;
                PollStatus          = errored ? "Failed" : "Completed";
                _pollSemaphoreSlim.Release();
            }
        }