Beispiel #1
0
 public bool TryGetItemKeys(string category, out IEnumerable <string> keys)
 {
     LogStart(nameof(TryGetItemKeys), category);
     try
     {
         return(_reader.TryGetItemKeys(category, out keys));
     }
     catch (Exception ex) when(LogError(nameof(TryGetItemKeys), ex, category))
     {
         throw;
     }
     finally
     {
         LogStop(nameof(TryGetItemKeys), category);
     }
 }
            /// <summary>
            /// Get the list of item keys belonging to the provided category.
            /// </summary>
            /// <param name="category">Category to retrieve keys for.</param>
            /// <param name="keys">Retrieved keys for the specified category.</param>
            /// <returns><b>true</b> if the category exists; otherwise, <b>false</b>.</returns>
            /// <exception cref="EngineUnloadedException">The request is rejected because the engine has been unloaded.</exception>
            /// <exception cref="ObjectDisposedException">The reader has been disposed.</exception>
            public bool TryGetItemKeys(string category, out IEnumerable <string> keys)
            {
                CheckAccess();

                return(_reader.TryGetItemKeys(category, out keys));
            }
Beispiel #3
0
 /// <summary>
 /// Gets the list of keys for the items on the heap.
 /// </summary>
 /// <param name="reader">The reader to obtain the list of keys from.</param>
 /// <param name="keys">The keys of the items on the heap.</param>
 /// <returns><c>true</c> if items were found and returned in <paramref name="keys"/>; otherwise, <c>false</c>.</returns>
 protected override bool TryGetItemKeysCore(IStateReader reader, out IEnumerable <string> keys) => reader.TryGetItemKeys(ItemsCategory, out keys);
 /// <summary>
 /// Gets a list of keys for the specified <paramref name="category"/>.
 /// </summary>
 /// <param name="category">The category within the persisted entity's state partition to get the keys for.</param>
 /// <param name="keys">The keys in the specified <paramref name="category"/>.</param>
 /// <returns><c>true</c> if the specified <paramref name="category"/> was found; otherwise, <c>false</c>.</returns>
 public bool TryGetItemKeys(string category, out IEnumerable <string> keys) => _reader.TryGetItemKeys(_prefix + category, out keys);
                /// <summary>
                /// Loads the definitions.
                /// </summary>
                /// <typeparam name="TEntity">The type of the entity.</typeparam>
                /// <param name="category">The category.</param>
                /// <param name="kind">Reactive entity kind.</param>
                /// <param name="onLoading">The function is called for each loading entity.</param>
                /// <param name="onError">Function to report an error.</param>
                /// <param name="blobLogger">The blob logger to write raw recovery blobs to.</param>
                /// <param name="token">Cancellation token</param>
                private void LoadDefinitions <TEntity>(
                    string category,
                    ReactiveEntityKind kind,
                    Action <TEntity> onLoading,
                    Action <string, TEntity, Exception> onError,
                    BlobLogger blobLogger,
                    CancellationToken token)
                    where TEntity : ReactiveEntity
                {
                    Debug.Assert(!string.IsNullOrEmpty(category), "Category should not be null or empty.");
                    Debug.Assert(onLoading != null, "onLoading should not be null.");

                    var trace = _engine.Parent.TraceSource;

                    trace.Recovery_LoadingDefinitionsStarted(_engine.Parent.Uri, category);

                    if (!_reader.TryGetItemKeys(category, out IEnumerable <string> entities))
                    {
                        entities = Array.Empty <string>();
                    }

                    var total  = 0;
                    var failed = 0;

                    Parallel.ForEach(
                        entities,
                        new ParallelOptions
                    {
                        MaxDegreeOfParallelism = _engine.Parent.Options.RecoveryDegreeOfParallelism,
                        TaskScheduler          = RecoveryScheduler.Default,
                        CancellationToken      = token,
                    },
                        key =>
                    {
                        var entity = default(TEntity);

                        try
                        {
                            var stopwatch = Stopwatch.StartNew();
                            if (!_reader.TryGetItemReader(category, key, out Stream stream))
                            {
                                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "No items in key '{0}' for category '{1}'.", key, category));
                            }
                            var elapsedReading = stopwatch.Elapsed;

                            blobLogger.Append(category, key, stream);

                            var policy = _engine.Parent._serializationPolicy;

                            stopwatch.Restart();
                            using (var reader = new EntityReader(stream, _engine.Registry, policy))
                            {
                                reader.ReadHeader();
                                _engine.TryMitigate(
                                    () => entity = (TEntity)reader.Load(kind),
                                    ReactiveEntity.CreateInvalidInstance(new Uri(key), kind),
                                    true,
                                    _placeholderMitigator);
                                reader.ReadFooter();
                            }
                            var elapsedLoading = stopwatch.Elapsed;

                            entity.SetMetric(EntityMetric.ReadEntity, elapsedReading);
                            entity.SetMetric(EntityMetric.LoadEntity, elapsedLoading);

                            onLoading(entity);
                        }
                        catch (MitigationBailOutException) { }
#pragma warning disable CA1031 // Do not catch general exception types. (By design; mitigation callback is the "handler".)
                        catch (Exception ex)
                        {
                            Interlocked.Increment(ref failed);

                            trace.Recovery_LoadingDefinitionsFailure(_engine.Parent.Uri, category, key, ex.Message);

                            onError(key, entity, ex);
                        }
#pragma warning restore CA1031

                        Interlocked.Increment(ref total);
                    });

                    token.ThrowIfCancellationRequested();

                    trace.Recovery_LoadingDefinitionsCompleted(_engine.Parent.Uri, category, total, failed);
                }