예제 #1
0
        /// <summary>
        /// RenewPeriodic is used to periodically invoke Session.Renew on a session until a CancellationToken is cancelled.
        /// This is meant to be used in a long running call to ensure a session stays valid until completed.
        /// </summary>
        /// <param name="initialTTL">The initital TTL to renew for</param>
        /// <param name="id">The session ID to renew</param>
        /// <param name="q">Customized write options</param>
        /// <param name="ct">The CancellationToken used to stop the session from being renewed (e.g. when the long-running action completes)</param>
        public Task RenewPeriodic(TimeSpan initialTTL, string id, WriteOptions q, CancellationToken ct)
        {
            return(Task.Factory.StartNew(async() =>
            {
                if (q == null)
                {
                    throw new ArgumentNullException(nameof(q));
                }
                var waitDuration = (int)(initialTTL.TotalMilliseconds / 2);
                var lastRenewTime = DateTime.Now;
                Exception lastException = new SessionExpiredException(string.Format("Session expired: {0}", id));
                try
                {
                    while (!ct.IsCancellationRequested)
                    {
                        if (DateTime.Now.Subtract(lastRenewTime) > initialTTL)
                        {
                            throw lastException;
                        }
                        try
                        {
                            await Task.Delay(waitDuration, ct).ConfigureAwait(false);
                        }
                        catch (OperationCanceledException)
                        {
                            // Ignore OperationCanceledException because it means the wait cancelled in response to a CancellationToken being cancelled.
                        }

                        try
                        {
                            var res = await Renew(id, q).ConfigureAwait(false);
                            initialTTL = res.Response.TTL ?? TimeSpan.Zero;
                            waitDuration = (int)(initialTTL.TotalMilliseconds / 2);
                            lastRenewTime = DateTime.Now;
                        }
                        catch (SessionExpiredException)
                        {
                            throw;
                        }
                        catch (OperationCanceledException)
                        {
                            // Ignore OperationCanceledException/TaskCanceledException since it means the session no longer exists or the task is stopping.
                        }
                        catch (Exception ex)
                        {
                            waitDuration = 1000;
                            lastException = ex;
                        }
                    }
                }
                finally
                {
                    if (ct.IsCancellationRequested)
                    {
                        await _client.Session.Destroy(id).ConfigureAwait(false);
                    }
                }
            }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default).Unwrap());
        }
예제 #2
0
        /// <summary>
        /// RenewPeriodic is used to periodically invoke Session.Renew on a session until a CancellationToken is cancelled.
        /// This is meant to be used in a long running call to ensure a session stays valid until completed.
        /// </summary>
        /// <param name="initialTTL">The initital TTL to renew for</param>
        /// <param name="id">The session ID to renew</param>
        /// <param name="q">Customized write options</param>
        /// <param name="ct">The CancellationToken used to stop the session from being renewed (e.g. when the long-running action completes)</param>
        public Task RenewPeriodic(TimeSpan initialTTL, string id, WriteOptions q, CancellationToken ct)
        {
            return(Task.Factory.StartNew(async() =>
            {
                if (q == null)
                {
                    throw new ArgumentNullException(nameof(q));
                }
                var waitDuration = TimeSpan.FromMilliseconds(initialTTL.TotalMilliseconds / 2);
                var sw = Stopwatch.StartNew();
                var ttl = initialTTL;

                Exception lastException = new SessionExpiredException(string.Format("Session expired: {0}", id));
                try
                {
                    while (!ct.IsCancellationRequested)
                    {
                        if (sw.Elapsed > ttl)
                        {
                            throw lastException;
                        }

                        try
                        {
                            await Task.Delay(waitDuration, ct).ConfigureAwait(false);

                            var res = await Renew(id, q).ConfigureAwait(false);
                            // Handle the server updating the TTL
                            ttl = res.Response.TTL ?? TimeSpan.Zero;
                            waitDuration = TimeSpan.FromMilliseconds(ttl.TotalMilliseconds / 2);
                            sw = Stopwatch.StartNew();
                        }
                        catch (SessionExpiredException)
                        {
                            throw;
                        }
                        catch (OperationCanceledException)
                        {
                            // Ignore OperationCanceledException/TaskCanceledException since it means the session no longer exists or the task is stopping.
                        }
                        catch (Exception ex)
                        {
                            waitDuration = TimeSpan.FromSeconds(1);
                            lastException = ex;
                        }
                    }
                }
                finally
                {
                    if (ct.IsCancellationRequested)
                    {
                        await _client.Session.Destroy(id).ConfigureAwait(false);
                    }
                }
            }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default).Unwrap());
        }