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)); }
/// <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); }