示例#1
0
        public virtual async Task <IAsyncEnumerable <T> > AsEnumerableAsync()
        {
            // The AsEnumerableAsync method always returns a value (never is null)
            // and we are not able to check if it is empty before starting enumerating it,
            // so we will start enumerate it and if there's at least one value, it is valid.

            // TODO: Peek only a value instead of enumerating completely
            var cacheEnumerable = await Cache.AsEnumerableAsync().ConfigureAwait(false);

            var cacheValues = await cacheEnumerable.ToArrayAsync().ConfigureAwait(false);

            if (cacheValues.Length > 0)
            {
                return(new AsyncEnumerableWrapper <T>(cacheValues));
            }

            var sourceEnumerable = await Source.AsEnumerableAsync().ConfigureAwait(false);

            var sourceValues = await sourceEnumerable.ToArrayAsync().ConfigureAwait(false);

            foreach (var sourceValue in sourceValues)
            {
                await Cache.AddAsync(sourceValue).ConfigureAwait(false);
            }

            return(new AsyncEnumerableWrapper <T>(sourceValues));
        }
        /// <summary>
        /// Updates an existing scope.
        /// </summary>
        /// <param name="scope">The scope to update.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
        /// <returns>
        /// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
        /// </returns>
        public virtual async Task UpdateAsync([NotNull] TScope scope, CancellationToken cancellationToken = default)
        {
            if (scope == null)
            {
                throw new ArgumentNullException(nameof(scope));
            }

            var results = await ValidateAsync(scope, cancellationToken);

            if (results.Any(result => result != ValidationResult.Success))
            {
                var builder = new StringBuilder();
                builder.AppendLine("One or more validation error(s) occurred while trying to update an existing scope:");
                builder.AppendLine();

                foreach (var result in results)
                {
                    builder.AppendLine(result.ErrorMessage);
                }

                throw new OpenIddictExceptions.ValidationException(builder.ToString(), results);
            }

            await Store.UpdateAsync(scope, cancellationToken);

            if (!Options.CurrentValue.DisableEntityCaching)
            {
                await Cache.RemoveAsync(scope, cancellationToken);

                await Cache.AddAsync(scope, cancellationToken);
            }
        }
示例#3
0
        public virtual async IAsyncEnumerable <T> AsEnumerableAsync([EnumeratorCancellation] CancellationToken cancellationToken = default)
        {
            // The AsEnumerableAsync method always returns a value (never is null)
            // and we are not able to check if it is empty before starting enumerating it,
            // so we will start enumerate it and if there's at least one value, it is valid.

            // TODO: Peek only a value instead of enumerating completely
            var cacheEnumerable = Cache.AsEnumerableAsync(cancellationToken);
            var cacheValues     = await cacheEnumerable.ToArrayAsync(cancellationToken).ConfigureAwait(false);

            if (cacheValues.Length > 0)
            {
                foreach (var cacheValue in cacheValues)
                {
                    yield return(cacheValue);
                }
            }
            else
            {
                var sourceEnumerable = Source.AsEnumerableAsync(cancellationToken);
                var sourceValues     = await sourceEnumerable.ToArrayAsync(cancellationToken).ConfigureAwait(false);

                foreach (var sourceValue in sourceValues)
                {
                    await Cache.AddAsync(sourceValue, cancellationToken).ConfigureAwait(false);
                }

                foreach (var sourceValue in sourceValues)
                {
                    yield return(sourceValue);
                }
            }
        }
示例#4
0
        private static async Task RunCacheTest(Cache cache)
        {
            await cache.ConnectAsync();

            Console.WriteLine("Enter 'key=value' to add a value to the cache.");
            Console.WriteLine("Enter 'key' to get a value from the cache.");
            Console.WriteLine("Enter '-key' to delete a value from the cache.");

            string line = null;

            while ((line = Console.ReadLine()) != null)
            {
                var values = line.Split('=');
                if (values.Length == 2)
                {
                    string key   = values[0].Trim();
                    string value = values[1].Trim();
                    await cache.AddAsync(key, value);

                    Console.WriteLine("Added '{0}' to the cache with value '{1}'.", key, value);
                }
                else if (line.StartsWith("-"))
                {
                    string key = line.Substring(1).Trim();
                    await cache.DeleteAsync(key);

                    Console.WriteLine("Deleting entry for key '{0}'", key);
                }
                else
                {
                    string key = line.Trim();
                    Console.WriteLine("Value for '{0}' is " + cache.Get(key), key);
                }
            }
        }
示例#5
0
        /// <summary>
        /// This method adds object in the cache using async api
        /// </summary>
        /// <param name="key"> String key to be added in cache</param>
        /// <param name="customer"> Instance of Customer that will be added to cache</param>
        private static void AddObjectToCacheAsynchronous(string key, Customer customer)
        {
            //Adding item asynchronously
            //Another way is by creating a CacheItem  object
            _cache.AddAsync(key, customer, new AsyncItemAddedCallback(OnItemAdded), string.Empty, string.Empty);

            // Wait for the callback.
            Thread.Sleep(1000);
        }
        private async Task SetLastSignupDateAsync(DateTime value)
        {
            await Cache.RemoveAsync($"{UserHostAddress}:LastSignupDate");

            if (value > DateTime.MinValue)
            {
                await Cache.AddAsync($"{UserHostAddress}:LastSignupDate", value,
                                     value.AddMinutes(SharedBusinessLogic.SharedOptions.MinSignupMinutes));
            }
        }
示例#7
0
        protected async Task SetLastPasswordResetDateAsync(DateTime value)
        {
            await Cache.RemoveAsync($"{UserHostAddress}:LastPasswordResetDate");

            if (value > DateTime.MinValue)
            {
                await Cache.AddAsync($"{UserHostAddress}:LastPasswordResetDate", value,
                                     value.AddMinutes(SharedBusinessLogic.SharedOptions.MinPasswordResetMinutes));
            }
        }
        /// <summary>
        /// Creates a new scope.
        /// </summary>
        /// <param name="scope">The scope to create.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
        /// <returns>
        /// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
        /// </returns>
        public virtual async ValueTask CreateAsync(TScope scope, CancellationToken cancellationToken = default)
        {
            if (scope is null)
            {
                throw new ArgumentNullException(nameof(scope));
            }

            var results = await GetValidationResultsAsync(scope, cancellationToken);

            if (results.Any(result => result != ValidationResult.Success))
            {
                var builder = new StringBuilder();
                builder.AppendLine(SR.GetResourceString(SR.ID0222));
                builder.AppendLine();

                foreach (var result in results)
                {
                    builder.AppendLine(result.ErrorMessage);
                }

                throw new OpenIddictExceptions.ValidationException(builder.ToString(), results);
            }

            await Store.CreateAsync(scope, cancellationToken);

            if (!Options.CurrentValue.DisableEntityCaching)
            {
                await Cache.AddAsync(scope, cancellationToken);
            }

            async Task <ImmutableArray <ValidationResult> > GetValidationResultsAsync(
                TScope scope, CancellationToken cancellationToken)
            {
                var builder = ImmutableArray.CreateBuilder <ValidationResult>();

                await foreach (var result in ValidateAsync(scope, cancellationToken))
                {
                    builder.Add(result);
                }

                return(builder.ToImmutable());
            }
        }
示例#9
0
        /// <summary>
        /// Asynchronously load a specific page.
        /// </summary>
        /// <param name="url">The URL of the page to load.  Cannot be null.</param>
        /// <param name="shortDescrip">A short description that can be used in status updates.  If null, no update will be given.</param>
        /// <param name="caching">Indicator of whether to query the cache for the requested page.</param>
        /// <param name="token">Cancellation token.</param>
        /// <param name="shouldCache">Indicates whether the result of this page load should be cached.</param>
        /// <returns>Returns an HTML document, if it can be loaded.</returns>
        /// <exception cref="ArgumentNullException">If url is null or empty.</exception>
        /// <exception cref="ArgumentException">If url is not a valid absolute url.</exception>
        private async Task <string> GetUrlContent(Uri uri, string url, string shortDescrip,
                                                  CachingMode caching, ShouldCache shouldCache, SuppressNotifications suppressNotifications, CancellationToken token)
        {
            string   result  = null;
            int      tries   = 0;
            DateTime expires = CacheInfo.DefaultExpiration;

            NotifyStatusChange(PageRequestStatusType.Requested, url, shortDescrip, null, suppressNotifications);

            // Limit to no more than N parallel requests
            await ss.WaitAsync(token).ConfigureAwait(false);

            try
            {
                Cookie cookie = ForumCookies.GetCookie(uri);
                if (cookie != null)
                {
                    ClientHandler.CookieContainer.Add(uri, cookie);
                }

                HttpResponseMessage        response;
                Task <HttpResponseMessage> getResponseTask = null;

                do
                {
                    token.ThrowIfCancellationRequested();

                    if (tries > 0)
                    {
                        // Delay any additional attempts after the first.
                        await Task.Delay(retryDelay, token).ConfigureAwait(false);

                        // Notify the user if we're re-trying to load the page.
                        NotifyStatusChange(PageRequestStatusType.Retry, url, shortDescrip, null, suppressNotifications);
                    }

                    tries++;

                    try
                    {
                        getResponseTask = client.GetAsync(uri, token).TimeoutAfter(timeout, token);
                        Debug.WriteLine($"Get URI {uri} task ID: {getResponseTask.Id}");

                        using (response = await getResponseTask.ConfigureAwait(false))
                        {
                            if (response.IsSuccessStatusCode)
                            {
                                result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                                // Get expires value
                                // Cannot get Expires value until we move to .NET Standard 2.0.

                                // If we get a successful result, we're done.
                                break;
                            }
                            else if (PageLoadFailed(response))
                            {
                                NotifyStatusChange(PageRequestStatusType.Failed, url,
                                                   GetFailureMessage(response, shortDescrip, url), null, suppressNotifications);
                                return(null);
                            }
                            else if (PageWasMoved(response))
                            {
                                url = response.Content.Headers.ContentLocation.AbsoluteUri;
                                uri = new Uri(url);
                            }
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        if (token.IsCancellationRequested)
                        {
                            // user request
                            throw;
                        }
                        else
                        {
                            // timeout via cancellation
                            Debug.WriteLine($"Attempt to load {shortDescrip} timed out/self-cancelled (TA). Tries={tries}");
                        }
                    }
                    catch (TimeoutException)
                    {
                        Debug.WriteLine($"Attempt to load {shortDescrip} timed out. Tries={tries}");
                    }
                    catch (HttpRequestException e)
                    {
                        NotifyStatusChange(PageRequestStatusType.Error, url, shortDescrip, e, suppressNotifications);
                        throw;
                    }
                } while (tries < retryLimit);

                Debug.WriteLine($"Finished getting URI {uri} task ID: {getResponseTask.Id}");

                if (result == null && tries >= retryLimit)
                {
                    client.CancelPendingRequests();
                }
            }
            catch (OperationCanceledException)
            {
                // If it's not a user-requested cancellation, generate a failure message.
                if (!token.IsCancellationRequested)
                {
                    NotifyStatusChange(PageRequestStatusType.Failed, url, shortDescrip, null, suppressNotifications);
                }

                throw;
            }
            finally
            {
                ss.Release();
            }

            token.ThrowIfCancellationRequested();

            if (result == null)
            {
                NotifyStatusChange(PageRequestStatusType.Failed, url, shortDescrip, null, suppressNotifications);
                return(null);
            }

            if (shouldCache == ShouldCache.Yes)
            {
                await Cache.AddAsync(url, result, expires);
            }

            NotifyStatusChange(PageRequestStatusType.Loaded, url, shortDescrip, null, suppressNotifications);

            return(result);
        }