private byte[] PersistentToBytes(SnapshotMetadata metadata, object snapshot) { var message = new SelectedSnapshot(metadata, snapshot); var serializer = _system.Serialization.FindSerializerForType(typeof(SelectedSnapshot)); return(serializer.ToBinary(message)); }
/// <summary> /// Asynchronously loads snapshot with the highest sequence number for a persistent actor/view matching specified criteria. /// </summary> protected async override Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria) { ServiceEventSource.Current.Message($"Entering ServiceFabricSnapshotStore.{nameof(LoadAsync)} PersistenceId: {persistenceId} "); SnapshotEntry snapshot = null; if (criteria.MaxSequenceNr > 0 && criteria.MaxSequenceNr < long.MaxValue) { var MaxNumberkey = $"{persistenceId}_{criteria.MaxSequenceNr}"; using (var tx = this.StateManager.CreateTransaction()) { ServiceEventSource.Current.Message($"{persistenceId} "); var snapshots = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, SnapshotEntry> >(persistenceId); var snapshotStorageCurrentHighSequenceNumber = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, long> >("SnapshotStorageCurrentHighSequenceNumber"); var maxSequenceNumberConditional = await snapshotStorageCurrentHighSequenceNumber.TryGetValueAsync(tx, persistenceId); if (maxSequenceNumberConditional.HasValue) { var MaxSequenceNumber = maxSequenceNumberConditional.Value; var ret = await snapshots.TryGetValueAsync(tx, $"{persistenceId}_{MaxSequenceNumber}"); snapshot = ret.HasValue ? ret.Value : null; await tx.CommitAsync(); SelectedSnapshot ss = new SelectedSnapshot(new SnapshotMetadata(persistenceId, snapshot.SequenceNr), snapshot); return(ss); } } } return(null); }
private byte[] PersistentToBytes(SnapshotMetadata metadata, object snapshot) { var message = new SelectedSnapshot(metadata, snapshot); var serializer = _system.Serialization.FindSerializerForType(typeof(SelectedSnapshot)); return(Akka.Serialization.Serialization.WithTransport(_system as ExtendedActorSystem, () => serializer.ToBinary(message))); //return serializer.ToBinary(message); }
protected override async Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria) { var snapshotEntry = repository.GetData<SnapshotEntry>(persistenceId, criteria.MaxSequenceNr, criteria.MaxTimeStamp); if (snapshotEntry == null) return (SelectedSnapshot) null; var snapshot = new SelectedSnapshot(new SnapshotMetadata(snapshotEntry.PersistenceId, snapshotEntry.SequenceNr, snapshotEntry.Timestamp), snapshotEntry.Snapshot); return snapshot; }
/// <summary> /// Finds the requested snapshot in the file and returns it. /// </summary> // [MethodImpl(MethodImplOptions.Synchronized)] private SelectedSnapshot Load(int streamId, SnapshotMetadata metadata) { _load++; if (_load % 10000 == 0) { _log.Info("Load() - count of calls={0}", _load); } // Get the snapshot map entry to locate where in the file the snapshot is stored if (!SnapshotMap.TryGetValue(metadata.PersistenceId, out var sme)) { return(null); } // _log.Debug("Load() - persistenceId={0}\t pos={1}\t length={2}", metadata.PersistenceId, sme.Position, sme.Length); // Find the id in the map to get the position within the file SelectedSnapshot snapshot = null; Monitor.Enter(_readStreams[streamId]); try { // Position to the saved location for the object _readStreams[streamId].Seek(sme.Position, SeekOrigin.Begin); // Get the snapshot file entry from the file var buffer = new byte[sme.Length]; _readStreams[streamId].Read(buffer, 0, sme.Length); var type = typeof(object); var serializer = _serialization.FindSerializerForType(type, _defaultSerializer); // Create the snapshot to return snapshot = new SelectedSnapshot(sme.Metadata, serializer.FromBinary(buffer, type)); // _log.Debug("Snapshot found for id: {0}", metadata.PersistenceId); } catch (SerializationException e) { _log.Error("Failed to deserialize. Reason: {0} at {1}", e.Message, e.StackTrace); throw e; } catch (Exception e) { _log.Error("Serious error while loading snapshot from store. msg={0}\n Postion:{1}", e.Message, e.StackTrace); throw e; } finally { Monitor.Exit(_readStreams[streamId]); } return(snapshot); }
protected override async Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria) { using var cts = new CancellationTokenSource(_settings.RequestTimeout); { var results = Container.GetBlobsAsync( prefix: SeqNoHelper.ToSnapshotSearchQuery(persistenceId), traits: BlobTraits.Metadata, cancellationToken: cts.Token); var pageEnumerator = results.AsPages().GetAsyncEnumerator(cts.Token); if (!await pageEnumerator.MoveNextAsync()) { return(null); } // TODO: see if there's ever a scenario where the most recent snapshots aren't in the first page of the pagination list. // apply filter criteria var filtered = pageEnumerator.Current.Values .Where(x => FilterBlobSeqNo(criteria, x)) .Where(x => FilterBlobTimestamp(criteria, x)) .OrderByDescending(FetchBlobSeqNo) // ordering matters - get highest seqNo item .ThenByDescending(FetchBlobTimestamp) // if there are multiple snapshots taken at same SeqNo, need latest timestamp .FirstOrDefault(); // couldn't find what we were looking for. Onto the next part of the query // or return null to sender possibly. if (filtered == null) { return(null); } using var memoryStream = new MemoryStream(); var blobClient = Container.GetBlockBlobClient(filtered.Name); var downloadInfo = await blobClient.DownloadAsync(cts.Token); await downloadInfo.Value.Content.CopyToAsync(memoryStream); var snapshot = _serialization.SnapshotFromBytes(memoryStream.ToArray()); var result = new SelectedSnapshot( new SnapshotMetadata( persistenceId, FetchBlobSeqNo(filtered), new DateTime(FetchBlobTimestamp(filtered))), snapshot.Data); return(result); } }
protected override async Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria) { var requestOptions = GenerateOptions(); BlobResultSegment results = null; using (var cts = new CancellationTokenSource(_settings.RequestTimeout)) { results = await Container.ListBlobsSegmentedAsync(SeqNoHelper.ToSnapshotSearchQuery(persistenceId), true, BlobListingDetails.Metadata, null, null, requestOptions, new OperationContext(), cts.Token); } // if we made it down here, the initial request succeeded. async Task <SelectedSnapshot> FilterAndFetch(BlobResultSegment segment) { // apply filter criteria var filtered = segment.Results .Where(x => x is CloudBlockBlob) .Cast <CloudBlockBlob>() .Where(x => FilterBlobSeqNo(criteria, x)) .Where(x => FilterBlobTimestamp(criteria, x)) .OrderByDescending(x => FetchBlobSeqNo(x)) // ordering matters - get highest seqNo item .ThenByDescending(x => FetchBlobTimestamp( x)) // if there are multiple snapshots taken at same SeqNo, need latest timestamp .FirstOrDefault(); // couldn't find what we were looking for. Onto the next part of the query // or return null to sender possibly. if (filtered == null) { return(null); } using (var cts = new CancellationTokenSource(_settings.RequestTimeout)) using (var memoryStream = new MemoryStream()) { await filtered.DownloadToStreamAsync(memoryStream, AccessCondition.GenerateEmptyCondition(), GenerateOptions(), new OperationContext(), cts.Token); var snapshot = _serialization.SnapshotFromBytes(memoryStream.ToArray()); var returnValue = new SelectedSnapshot( new SnapshotMetadata( persistenceId, FetchBlobSeqNo(filtered), new DateTime(FetchBlobTimestamp(filtered))), snapshot.Data); return(returnValue); } } // TODO: see if there's ever a scenario where the most recent snapshots aren't in the beginning of the pagination list. var result = await FilterAndFetch(results); return(result); }