public bool TryRemove(TKey key, out TValue value)
        {
            var stopwatch = StopwatchStruct.StartNew();

            try
            {
                var removed = _innerCache.TryRemove(key, out value);

                OnTryRemoveCompletedSuccessfully(key, removed, value, stopwatch.Elapsed);

                return(removed);
            }
            catch (Exception ex)
            {
                OnTryRemoveException(key, stopwatch.Elapsed, ex, out var exceptionHandled);

                if (!exceptionHandled)
                {
                    throw;
                }

                value = default;
                return(false);
            }
        }
        public int GetMany(ReadOnlySpan <TKey> keys, Span <KeyValuePair <TKey, TValue> > destination)
        {
            var stopwatch = StopwatchStruct.StartNew();

            try
            {
                var countFound = _innerCache.GetMany(keys, destination);

                var values = destination.Slice(0, countFound);

                OnGetManyCompletedSuccessfully(keys, values, stopwatch.Elapsed);

                return(countFound);
            }
            catch (Exception ex)
            {
                OnGetManyException(keys, stopwatch.Elapsed, ex, out var exceptionHandled);

                if (!exceptionHandled)
                {
                    throw;
                }

                return(0);
            }
        }
Esempio n. 3
0
        private protected async Task UpdateValueWithinLock(
            Func <T, TUpdates, CancellationToken, Task <T> > applyUpdatesFunc,
            TUpdates updates,
            CancellationToken cancellationToken)
        {
            var stopwatch = StopwatchStruct.StartNew();

            try
            {
                var previousValue = _value;
                _value = await applyUpdatesFunc(_value, updates, cancellationToken).ConfigureAwait(false);

                Interlocked.Increment(ref _version);

                PublishValueUpdatedEvent(previousValue, updates, stopwatch.Elapsed);
            }
            catch (Exception ex)
            {
                PublishValueUpdateExceptionEvent(ex, updates, stopwatch.Elapsed);
                throw;
            }
            finally
            {
                ReleaseRefreshOrUpdateValueLock();
            }
        }
        public void MeasuresTimeAccurately()
        {
            var timer1 = StopwatchStruct.StartNew();
            var timer2 = Stopwatch.StartNew();

            Thread.Sleep(TimeSpan.FromSeconds(1));

            timer1.Elapsed.Should().BeCloseTo(timer2.Elapsed);
        }
Esempio n. 5
0
        private bool FlushPayload(string path, PayloadQueue queue)
        {
            var payload = queue.DequeuePendingPayload();

            if (payload == null)
            {
                return(false);
            }

            var metricsCount = payload.MetricsCount;
            var bytes        = payload.Used;

            Debug.WriteLine($"BosunReporter: Flushing metrics batch. {metricsCount} metrics. {bytes} bytes.");

            var info  = new AfterPostInfo();
            var timer = new StopwatchStruct();

            try
            {
                timer.Start();
                PostToBosun(path, true, sw => sw.Write(payload.Data, 0, payload.Used));
                timer.Stop();

                queue.ReleasePayload(payload);

                PostSuccessCount++;
                TotalMetricsPosted += payload.MetricsCount;

                return(true);
            }
            catch (Exception ex)
            {
                timer.Stop();
                // posting to Bosun failed, so put the batch back in the queue to try again later
                Debug.WriteLine("BosunReporter: Posting to the Bosun API failed. Pushing metrics back onto the queue.");
                PostFailCount++;
                info.Exception = ex;
                queue.AddPendingPayload(payload);
                throw;
            }
            finally
            {
                // don't use the payload variable in this block - it may have been released back to the pool by now
                info.Count                = metricsCount;
                info.BytesWritten         = bytes;
                info.MillisecondsDuration = timer.GetElapsedMilliseconds();
                LastPostInfo              = info;

                // Use BeginInvoke here to invoke the event listeners asynchronously.
                // We're inside a lock, so calling the listeners synchronously would put us at risk of a deadlock.
                AfterPost?.BeginInvoke(info, s_asyncNoopCallback, null);
            }
        }
Esempio n. 6
0
        private void Snapshot(object isCalledFromTimer)
        {
            if ((bool)isCalledFromTimer && ShutdownCalled) // don't perform timer actions if we're shutting down
            {
                return;
            }

            if (GetBosunUrl != null)
            {
                BosunUrl = GetBosunUrl();
            }


            try
            {
                if (BeforeSerialization != null && BeforeSerialization.GetInvocationList().Length != 0)
                {
                    BeforeSerialization();
                }

                var sw = new StopwatchStruct();
                sw.Start();
                int metricsCount, bytesWritten;
                SerializeMetrics(out metricsCount, out bytesWritten);
                sw.Stop();

                var info = new AfterSerializationInfo
                {
                    Count                = metricsCount,
                    BytesWritten         = bytesWritten,
                    MillisecondsDuration = sw.GetElapsedMilliseconds(),
                };

                LastSerializationInfo = info;
                AfterSerialization?.Invoke(info);
            }
            catch (Exception ex)
            {
                if (ShouldThrowException(ex))
                {
                    if (HasExceptionHandler)
                    {
                        OnBackgroundException(ex);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
Esempio n. 7
0
        private void Snapshot(object isCalledFromTimer)
        {
            if ((bool)isCalledFromTimer && ShutdownCalled) // don't perform timer actions if we're shutting down
            {
                return;
            }

            if (GetBosunUrl != null)
            {
                BosunUrl = GetBosunUrl();
            }


            try
            {
                if (BeforeSerialization != null && BeforeSerialization.GetInvocationList().Length != 0)
                {
                    BeforeSerialization();
                }

                var info = new AfterSerializationInfo();
                var sw   = new StopwatchStruct();
                sw.Start();
                var list = GetSerializedMetrics();
                sw.Stop();

                EnqueueMetrics(list);

                info.Count = list.Count;
                info.MillisecondsDuration = sw.GetElapsedMilliseconds();

                LastSerializationInfo = info;
                AfterSerialization?.Invoke(info);
            }
            catch (Exception e)
            {
                if (HasExceptionHandler)
                {
                    OnBackgroundException(e);
                    return;
                }

                throw;
            }
        }
Esempio n. 8
0
        private void FlushBatch()
        {
            var batch = DequeueMetricsBatch();

            if (batch.Count == 0)
            {
                return;
            }

            Debug.WriteLine("BosunReporter: Flushing metrics batch. Size: " + batch.Count);

            var info  = new AfterPostInfo();
            var timer = new StopwatchStruct();

            try
            {
                timer.Start();
                PostToBosun("/api/put", true, sw => WriteJsonArrayBody(sw, batch));
                timer.Stop();

                PostSuccessCount++;
                TotalMetricsPosted += batch.Count;
            }
            catch (Exception ex)
            {
                timer.Stop();
                // posting to Bosun failed, so put the batch back in the queue to try again later
                Debug.WriteLine("BosunReporter: Posting to the Bosun API failed. Pushing metrics back onto the queue.");
                PostFailCount++;
                info.Exception = ex;
                EnqueueMetrics(batch);
                throw;
            }
            finally
            {
                info.Count = batch.Count;
                info.MillisecondsDuration = timer.GetElapsedMilliseconds();
                LastPostInfo = info;

                // Use BeginInvoke here to invoke the event listeners asynchronously.
                // We're inside a lock, so calling the listeners synchronously would put us at risk of a deadlock.
                AfterPost?.BeginInvoke(info, s_asyncNoopCallback, null);
            }
        }
        public void ResultMatchesStopwatch()
        {
            var sw = Stopwatch.StartNew();
            var ss = new StopwatchStruct();

            ss.Start();

            Thread.Sleep(500);

            sw.Stop();
            ss.Stop();

            var swMs = sw.Elapsed.TotalMilliseconds;
            var ssMs = ss.GetElapsedMilliseconds();

            var difference = Math.Abs(swMs - ssMs);

            Assert.IsTrue(difference < 1);
        }
        public void Set(TKey key, TValue value, TimeSpan timeToLive)
        {
            var stopwatch = StopwatchStruct.StartNew();

            try
            {
                _innerCache.Set(key, value, timeToLive);

                OnSetCompletedSuccessfully(key, value, timeToLive, stopwatch.Elapsed);
            }
            catch (Exception ex)
            {
                OnSetException(key, value, timeToLive, stopwatch.Elapsed, ex, out var exceptionHandled);

                if (!exceptionHandled)
                {
                    throw;
                }
            }
        }
        public void SetMany(ReadOnlySpan <KeyValuePair <TKey, TValue> > values, TimeSpan timeToLive)
        {
            var stopwatch = StopwatchStruct.StartNew();

            try
            {
                _innerCache.SetMany(values, timeToLive);

                OnSetManyCompletedSuccessfully(values, timeToLive, stopwatch.Elapsed);
            }
            catch (Exception ex)
            {
                OnSetManyException(values, timeToLive, stopwatch.Elapsed, ex, out var exceptionHandled);

                if (!exceptionHandled)
                {
                    throw;
                }
            }
        }
        public async Task <(bool Success, ValueAndTimeToLive <TValue> Value)> TryGet(TKey key)
        {
            var stopwatch = StopwatchStruct.StartNew();

            try
            {
                var result = await _innerCache
                             .TryGet(key)
                             .ConfigureAwait(false);

                OnTryGetCompletedSuccessfully(key, result.Success, result.Value, stopwatch.Elapsed);

                return(result);
            }
            catch (Exception ex)
            {
                OnTryGetException(key, stopwatch.Elapsed, ex, out var exceptionHandled);

                if (!exceptionHandled)
                {
                    throw;
                }

                return(default);
Esempio n. 13
0
        public async Task InitializeAsync(CancellationToken cancellationToken = default)
        {
            TaskCompletionSource <bool> tcs;
            var initializationAlreadyInProgress = false;

            lock (_lock)
            {
                switch (_state)
                {
                case Disposed:
                    throw GetObjectDisposedException();

                case Ready:
                    return;

                case InitializationInProgress:
                    tcs = _initializationTaskCompletionSource;
                    initializationAlreadyInProgress = true;
                    break;

                case PendingInitialization:
                    tcs    = _initializationTaskCompletionSource = new TaskCompletionSource <bool>();
                    _state = InitializationInProgress;
                    break;

                default:
                    throw new InvalidOperationException("Invalid state - " + _state);
                }
            }

            if (initializationAlreadyInProgress)
            {
                await tcs.Task.ConfigureAwait(false);

                return;
            }

            var start     = DateTime.UtcNow;
            var stopwatch = StopwatchStruct.StartNew();

            CancellationTokenSource cts = null;

            try
            {
                if (_refreshValueFuncTimeout.HasValue)
                {
                    cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

                    cts.CancelAfter(_refreshValueFuncTimeout.Value);

                    cancellationToken = cts.Token;
                }

                _value = await _getValueFunc(cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                lock (_lock)
                {
                    ThrowIfDisposed();
                    _state = PendingInitialization;
                    _initializationTaskCompletionSource = null;
                }

                PublishValueRefreshExceptionEvent(ex, stopwatch.Elapsed);
                tcs.TrySetException(ex);

                throw;
            }
            finally
            {
                cts?.Dispose();
            }

            lock (_lock)
            {
                ThrowIfDisposed();
                _version = 1;
                _state   = Ready;
                _initializationTaskCompletionSource = null;
            }

            OnInitialized?.Invoke(this, null);
            tcs.TrySetResult(true);

            PublishValueRefreshedEvent(default, stopwatch.Elapsed);