protected override bool Receive(object message) { if (message is LoadSnapshot) { var msg = (LoadSnapshot)message; LoadAsync(msg.PersistenceId, msg.Criteria.Limit(msg.ToSequenceNr)) .ContinueWith(t => !t.IsFaulted ? new LoadSnapshotResult(t.Result, msg.ToSequenceNr) : new LoadSnapshotResult(null, msg.ToSequenceNr)) .PipeTo(Sender); } else if (message is SaveSnapshot) { var msg = (SaveSnapshot)message; var metadata = new SnapshotMetadata(msg.Metadata.PersistenceId, msg.Metadata.SequenceNr, DateTime.UtcNow); SaveAsync(metadata, msg.Snapshot).ContinueWith(t => !t.IsFaulted ? (object)new SaveSnapshotSuccess(metadata) : new SaveSnapshotFailure(msg.Metadata, t.Exception)) .PipeTo(Self, Sender); } else if (message is SaveSnapshotSuccess) { var msg = (SaveSnapshotSuccess)message; Saved(msg.Metadata); Sender.Tell(message); // Sender is PersistentActor } else if (message is SaveSnapshotFailure) { var msg = (SaveSnapshotFailure)message; Delete(msg.Metadata); Sender.Tell(message); // Sender is PersistentActor } else if (message is DeleteSnapshot) { var msg = (DeleteSnapshot)message; Delete(msg.Metadata); if (_publish) { Context.System.EventStream.Publish(message); } } else if (message is DeleteSnapshots) { var msg = (DeleteSnapshots) message; Delete(msg.PersistenceId, msg.Criteria); if (_publish) { Context.System.EventStream.Publish(message); } } else return false; return true; }
protected override async Task SaveAsync(SnapshotMetadata metadata, object snapshot) { var snapshotEntry = ToSnapshotEntry(metadata, snapshot); await _snapshotCollection.Value.ReplaceOneAsync( CreateSnapshotIdFilter(snapshotEntry.Id), snapshotEntry, new UpdateOptions { IsUpsert = true }); }
private IEnumerable<SnapshotMetadata> WriteSnapshots() { for (int i = 1; i <= 5; i++) { var metadata = new SnapshotMetadata(Pid, i + 10); SnapshotStore.Tell(new SaveSnapshot(metadata, "s-" + i), _senderProbe.Ref); yield return _senderProbe.ExpectMsg<SaveSnapshotSuccess>().Metadata; } }
async private Task SaveAsyncTask(object snapshot, SnapshotMetadata metadata) { await Task.Run(() => { Document<SnapshotEntry> SnapshotEntryDocument = ToSnapshotEntryDocument(snapshot, metadata); _CBBucket.UpsertAsync<SnapshotEntry>(SnapshotEntryDocument); }); }
public SelectedSnapshot Map(DbDataReader reader) { var persistenceId = reader.GetString(0); var sequenceNr = reader.GetInt64(1); var timestamp = new DateTime(reader.GetInt64(2)); var metadata = new SnapshotMetadata(persistenceId, sequenceNr, timestamp); var snapshot = GetSnapshot(reader); return new SelectedSnapshot(metadata, snapshot); }
protected override Task DeleteAsync(SnapshotMetadata metadata) { var builder = Builders<SnapshotEntry>.Filter; var filter = builder.Eq(x => x.PersistenceId, metadata.PersistenceId); if (metadata.SequenceNr > 0 && metadata.SequenceNr < long.MaxValue) filter &= builder.Eq(x => x.SequenceNr, metadata.SequenceNr); if (metadata.Timestamp != DateTime.MinValue && metadata.Timestamp != DateTime.MaxValue) filter &= builder.Eq(x => x.Timestamp, metadata.Timestamp.Ticks); return _snapshotCollection.Value.FindOneAndDeleteAsync(filter); }
private Document <SnapshotEntry> ToSnapshotEntryDocument(object snapshot, SnapshotMetadata metadata) { return(new Document <SnapshotEntry> { Id = metadata.PersistenceId + "_" + metadata.SequenceNr.ToString(), Content = new SnapshotEntry { Id = metadata.PersistenceId + "_" + metadata.SequenceNr, PersistenceId = metadata.PersistenceId, SequenceNr = metadata.SequenceNr, Snapshot = snapshot, Timestamp = metadata.Timestamp.Ticks.ToString() } }); }
/// <summary> /// TBD /// </summary> /// <param name="metadata">TBD</param> /// <returns>TBD</returns> protected override Task DeleteAsync(SnapshotMetadata metadata) { _saving.Remove(metadata); return(RunWithStreamDispatcher(() => { // multiple snapshot files here mean that there were multiple snapshots for this seqNr, we delete all of them // usually snapshot-stores would keep one snapshot per sequenceNr however here in the file-based one we timestamp // snapshots and allow multiple to be kept around (for the same seqNr) if desired foreach (var file in GetSnapshotFiles(metadata)) { file.Delete(); } return new object(); })); }
protected override async Task SaveAsync(SnapshotMetadata metadata, object snapshot) { var snapData = new Snapshot(Guid.NewGuid(), metadata.PersistenceId, typeof(Snapshot).Name, metadata.SequenceNr, new SelectedSnapshot(metadata, snapshot)); try { CloudTableClient tableClient = _extension.TableSnapshotStoreSettings.GetClient(metadata.PersistenceId); CloudTable table = tableClient.GetTableReference(_extension.TableSnapshotStoreSettings.TableName); TableOperation insertOperation = TableOperation.Insert(snapData); TableResult result = await table.ExecuteAsync(insertOperation); } catch (Exception ex) { _log.Error(ex,ex.Message); } }
public virtual void SnapshotStore_should_serialize_Payload_with_string_manifest() { var probe = CreateTestProbe(); var snapshot = new Test.MySnapshot2("a"); var metadata = new SnapshotMetadata(Pid, 1); SnapshotStore.Tell(new SaveSnapshot(metadata, snapshot), probe.Ref); probe.ExpectMsg <SaveSnapshotSuccess>(); SnapshotStore.Tell(new LoadSnapshot(Pid, SnapshotSelectionCriteria.Latest, long.MaxValue), probe.Ref); probe.ExpectMsg <LoadSnapshotResult>(s => s.Snapshot.Snapshot is Test.MySnapshot2 && s.Snapshot.Snapshot.AsInstanceOf <Test.MySnapshot2>().Data.Equals(".a.")); }
public virtual void SnapshotStore_should_serialize_AtLeastOnceDeliverySnapshot_with_empty_unconfirmed() { var probe = CreateTestProbe(); var unconfirmed = new UnconfirmedDelivery[0]; var atLeastOnceDeliverySnapshot = new AtLeastOnceDeliverySnapshot(13, unconfirmed); var metadata = new SnapshotMetadata(Pid, 2); SnapshotStore.Tell(new SaveSnapshot(metadata, atLeastOnceDeliverySnapshot), probe.Ref); probe.ExpectMsg <SaveSnapshotSuccess>(); SnapshotStore.Tell(new LoadSnapshot(Pid, SnapshotSelectionCriteria.Latest, long.MaxValue), probe.Ref); probe.ExpectMsg <LoadSnapshotResult>(s => s.Snapshot.Snapshot.Equals(atLeastOnceDeliverySnapshot)); }
protected override Task SaveAsync(SnapshotMetadata metadata, object snapshot) { var entry = ToSnapshotEntry(metadata, snapshot); var sqlCommand = QueryBuilder.InsertSnapshot(entry); CompleteCommand(sqlCommand); var tokenSource = GetCancellationTokenSource(); return(sqlCommand.ExecuteNonQueryAsync(tokenSource.Token) .ContinueWith(task => { PendingOperations.Remove(tokenSource); }, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.AttachedToParent)); }
private void Save(SnapshotMetadata metadata, object payload) { var tempFile = GetSnapshotFile(metadata, ".tmp"); using (var stream = tempFile.OpenWrite()) { var snapshot = new Serialization.Snapshot(payload); Serialize(snapshot, stream); } // remove .tmp extension and rename var newFilePath = tempFile.FullName.Substring(0, tempFile.FullName.Length - 4); File.Move(tempFile.FullName, newFilePath); }
protected override async Task SaveAsync(SnapshotMetadata metadata, object snapshot) { var snapData = new Snapshot(Guid.NewGuid(), metadata.PersistenceId, typeof(Snapshot).Name, metadata.SequenceNr, new SelectedSnapshot(metadata, snapshot)); try { CloudTableClient tableClient = _extension.TableSnapshotStoreSettings.GetClient(metadata.PersistenceId); CloudTable table = tableClient.GetTableReference(_extension.TableSnapshotStoreSettings.TableName); TableOperation insertOperation = TableOperation.Insert(snapData); TableResult result = await table.ExecuteAsync(insertOperation); } catch (Exception ex) { _log.Error(ex, ex.Message); } }
protected override Task SaveAsync(SnapshotMetadata metadata, object snapshot) { var snapshotEntry = new SnapshotEntry { Id = metadata.PersistenceId + "_" + metadata.SequenceNr, PersistenceId = metadata.PersistenceId, SequenceNr = metadata.SequenceNr, Snapshot = snapshot, Timestamp = metadata.Timestamp.Ticks }; // throws a MongoWriteException if s snapshot with the same PersistenceId and SequenceNr // is inserted the second time. As @Horusiath pointed out, that's fine, because a second snapshot // without any events in the meantime doesn't make any sense. return _collection.InsertOneAsync(snapshotEntry); }
protected override async Task SaveAsync(SnapshotMetadata metadata, object snapshot) { var connection = await GetConnection(); var streamName = GetStreamName(metadata.PersistenceId, _extension.TenantIdentifier); // Serializes the snapshot using Akka default serializer, currently JSON but will soon default to Wire. // Setting IsJson false means it will be ignored by EventStore projections var data = _serializer.ToBinary(ToSnapshotEntry(metadata, snapshot)); var eventData = new EventData(Guid.NewGuid(), typeof(SnapshotRepresentation).Name, false, data, new byte[0]); _log.Debug($"Saving Snap Shot {streamName}"); await connection.AppendToStreamAsync(streamName, ExpectedVersion.Any, eventData); await Task.CompletedTask; }
protected override async Task DeleteAsync(SnapshotMetadata metadata) { try { CloudTableClient tableClient = _extension.TableSnapshotStoreSettings.GetClient(metadata.PersistenceId); CloudTable table = tableClient.GetTableReference(_extension.TableSnapshotStoreSettings.TableName); TableOperation getOperation = TableOperation.Retrieve<Snapshot>(metadata.PersistenceId, Snapshot.ToRowKey(metadata.SequenceNr)); TableResult result = table.Execute(getOperation); TableOperation deleteOperation = TableOperation.Delete((Snapshot)result.Result); result = table.Execute(deleteOperation); } catch (Exception ex) { _log.Error(ex, ex.Message); } }
private SnapshotEntry ToSnapshotEntry(SnapshotMetadata metadata, object snapshot) { var snapshotType = snapshot.GetType(); var serializer = Context.System.Serialization.FindSerializerForType(snapshotType, _settings.DefaultSerializer); var binary = Akka.Serialization.Serialization.WithTransport(_actorSystem, () => serializer.ToBinary(snapshot)); return(new SnapshotEntry( persistenceId: metadata.PersistenceId, sequenceNr: metadata.SequenceNr, timestamp: metadata.Timestamp, manifest: snapshotType.TypeQualifiedName(), payload: binary)); }
protected override async Task DeleteAsync(SnapshotMetadata metadata) { try { CloudTableClient tableClient = _extension.TableSnapshotStoreSettings.GetClient(metadata.PersistenceId); CloudTable table = tableClient.GetTableReference(_extension.TableSnapshotStoreSettings.TableName); TableOperation getOperation = TableOperation.Retrieve <Snapshot>(metadata.PersistenceId, Snapshot.ToRowKey(metadata.SequenceNr)); TableResult result = table.Execute(getOperation); TableOperation deleteOperation = TableOperation.Delete((Snapshot)result.Result); result = table.Execute(deleteOperation); } catch (Exception ex) { _log.Error(ex, ex.Message); } }
protected override Task SaveAsync(SnapshotMetadata metadata, object snapshot) { var snapshotEntry = new SnapshotEntry { Id = metadata.PersistenceId + "_" + metadata.SequenceNr, PersistenceId = metadata.PersistenceId, SequenceNr = metadata.SequenceNr, Snapshot = snapshot, Timestamp = metadata.Timestamp.Ticks }; // throws a MongoWriteException if s snapshot with the same PersistenceId and SequenceNr // is inserted the second time. As @Horusiath pointed out, that's fine, because a second snapshot // without any events in the meantime doesn't make any sense. return(_collection.InsertOneAsync(snapshotEntry)); }
/// <summary> /// Asynchronously saves a snapshot. /// This call is protected with a circuit-breaker /// </summary> protected override Task SaveAsync(SnapshotMetadata metadata, object snapshot) { var table = _client.Value.GetTableReference(_settings.TableName); TableOperation upsertOperation = TableOperation.Insert(ToSnapshotEntry(metadata, snapshot)); var entity = (SnapshotEntry)table.Execute(TableOperation.Retrieve <SnapshotEntry>(metadata.PersistenceId, SnapshotEntry.ToRowKey(metadata.SequenceNr))).Result; if (entity != null) { entity.Payload = JsonConvert.SerializeObject(snapshot); upsertOperation = TableOperation.Replace(entity); } return(table.ExecuteAsync(upsertOperation)); }
/// <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 % 100000 == 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 Task SaveAsync(SnapshotMetadata metadata, object snapshot) { var snapshotEntry = ToSnapshotEntry(metadata, snapshot); var existingSnapshot = Snapshots.FirstOrDefault(CreateSnapshotIdFilter(snapshotEntry.Id)); if (existingSnapshot != null) { existingSnapshot.Snapshot = snapshotEntry.Snapshot; existingSnapshot.Timestamp = snapshotEntry.Timestamp; } else { Snapshots.Add(snapshotEntry); } return(TaskEx.Completed); }
protected async override Task DeleteAsync(SnapshotMetadata metadata) { ServiceEventSource.Current.Message($"Entering ServiceFabricSnapshotStore.{nameof(DeleteAsync)} PersistenceId: {metadata.PersistenceId} SequencNumer: {metadata.SequenceNr}"); using (var tx = this.StateManager.CreateTransaction()) { var snapshots = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, SnapshotEntry> >(metadata.PersistenceId); var removed = await snapshots.TryRemoveAsync(tx, $"{metadata.PersistenceId}_{metadata.SequenceNr}"); if (removed.HasValue) { var result = removed.Value; } await tx.CommitAsync(); } }
protected override Task DeleteAsync(SnapshotMetadata metadata) { var builder = Builders <SnapshotEntry> .Filter; var filter = builder.Eq(x => x.PersistenceId, metadata.PersistenceId); if (metadata.SequenceNr > 0 && metadata.SequenceNr < long.MaxValue) { filter &= builder.Eq(x => x.SequenceNr, metadata.SequenceNr); } if (metadata.Timestamp != DateTime.MinValue && metadata.Timestamp != DateTime.MaxValue) { filter &= builder.Eq(x => x.Timestamp, metadata.Timestamp.Ticks); } return(_snapshotCollection.Value.FindOneAndDeleteAsync(filter)); }
protected IActorRef WriteSnapshot(string persistenceId, int n) { var pref = Sys.ActorOf(Query.TestActor.Props(persistenceId)); for (var i = 1; i <= n; i++) { pref.Tell($"{persistenceId}-{i}"); ExpectMsg($"{persistenceId}-{i}-done"); } var metadata = new SnapshotMetadata(persistenceId, n + 10); SnapshotStore.Tell(new SaveSnapshot(metadata, $"s-{n}"), _senderProbe.Ref); _senderProbe.ExpectMsg <SaveSnapshotSuccess>(); return(pref); }
public EventData Adapt(SnapshotMetadata snapshotMetadata, object snapshot) { var @event = snapshot; var metadata = JObject.Parse("{}"); metadata[Constants.EventMetadata.PersistenceId] = snapshotMetadata.PersistenceId; metadata[Constants.EventMetadata.OccurredOn] = DateTimeOffset.Now; metadata[Constants.EventMetadata.SequenceNr] = snapshotMetadata.SequenceNr; metadata[Constants.EventMetadata.Timestamp] = snapshotMetadata.Timestamp; metadata[Constants.EventMetadata.JournalType] = Constants.JournalTypes.SnapshotJournal; var dataBytes = ToBytes(@event, metadata, out var type, out var isJson); var metadataString = JsonConvert.SerializeObject(metadata, _settings); var metadataBytes = Encoding.UTF8.GetBytes(metadataString); return(new EventData(Guid.NewGuid(), type, isJson, dataBytes, metadataBytes)); }
protected override async Task SaveAsync(SnapshotMetadata metadata, object snapshot) { await Task.Run(() => { var snapshotEntry = ToSnapshotEntry(metadata, snapshot); var existingSnapshot = Snapshots.FirstOrDefault(CreateSnapshotIdFilter(snapshotEntry.Id)); if (existingSnapshot != null) { existingSnapshot.Snapshot = snapshotEntry.Snapshot; existingSnapshot.Timestamp = snapshotEntry.Timestamp; } else { Snapshots.Add(snapshotEntry); } }); }
/// <summary> /// Stores the snapshot in the file asdynchronously /// </summary> protected override Task SaveAsync(SnapshotMetadata metadata, object snapshot) { try { _saveasync++; if (_saveasync % 100000 == 0) { _log.Info("SaveAsync() - count of calls={0}", _saveasync); } return(RunWithStreamDispatcher(() => { Save(metadata, snapshot); return new object(); })); } catch (Exception e) { _log.Error("ERROR in LoadAsync(). Message={0}\nStacktrace={1}", e.Message, e.StackTrace); return(null); } }
public SelectedSnapshot Adapt(ResolvedEvent resolvedEvent) { var eventData = resolvedEvent.Event; var metadataString = Encoding.UTF8.GetString(eventData.Metadata); var metadata = JsonConvert.DeserializeObject <JObject>(metadataString, _settings); var stream = (string)metadata.SelectToken(Constants.EventMetadata.PersistenceId); var sequenceNr = (long)metadata.SelectToken(Constants.EventMetadata.SequenceNr); var ts = (string)metadata.SelectToken(Constants.EventMetadata.Timestamp); var timestamp = metadata.Value <DateTime>(Constants.EventMetadata.Timestamp); var @event = ToEvent(resolvedEvent.Event.Data, metadata); var snapshotMetadata = new SnapshotMetadata(stream, sequenceNr, timestamp); return(new SelectedSnapshot(snapshotMetadata, @event)); }
public SelectedSnapshot Map(SnapshotEntry e) { if (e == null) return null; var persistenceId = e.PersistenceId; var sequenceNr = e.SequenceNr; var timestamp = e.Timestamp; var metadata = new SnapshotMetadata(persistenceId, sequenceNr, timestamp); var type = Type.GetType(e.SnapshotType, true); var serializer = _serialization.FindSerializerForType(type); var binary = e.Snapshot; var snapshot = serializer.FromBinary(binary, type); return new SelectedSnapshot(metadata, snapshot); }
protected override async Task DeleteAsync(SnapshotMetadata metadata) { var filter = Filter.And( Filter.HasAncestor(RootKey(metadata.PersistenceId)), Filter.Equal(SnapshotFields.SequenceNr, metadata.SequenceNr) //,Filter.Equal(SnapshotFields.Timestamp, metadata.Timestamp.Ticks) ); Query query = new Query(_snapshotKind) { Filter = filter, Order = { { JournalFields.SequenceNr, PropertyOrder.Types.Direction.Ascending } } }; var results = await _db.RunQueryAsync(query).ConfigureAwait(false); await _db.DeleteAsync(results.Entities); await CheckDeleteRootsnapshot(metadata.PersistenceId, metadata.SequenceNr, metadata.Timestamp.Ticks); }
public void SnapshotStore_should_delete_a_single_snapshot_identified_by_SequenceNr_in_snapshot_metadata() { var md = Metadata[2]; md = new SnapshotMetadata(md.PersistenceId, md.SequenceNr); // don't care about timestamp for delete of a single snap var command = new DeleteSnapshot(md); var sub = CreateTestProbe(); Subscribe <DeleteSnapshot>(sub.Ref); SnapshotStore.Tell(command, _senderProbe.Ref); sub.ExpectMsg(command); _senderProbe.ExpectMsg <DeleteSnapshotSuccess>(); SnapshotStore.Tell(new LoadSnapshot(Pid, new SnapshotSelectionCriteria(md.SequenceNr), long.MaxValue), _senderProbe.Ref); _senderProbe.ExpectMsg <LoadSnapshotResult>(result => result.ToSequenceNr == long.MaxValue && result.Snapshot != null && result.Snapshot.Metadata.Equals(Metadata[1]) && result.Snapshot.Snapshot.ToString() == "s-2"); }
/// <summary> /// Asynchronously stores a snapshot with metadata as record in SQL table. /// </summary> protected override async Task SaveAsync(SnapshotMetadata metadata, object snapshot) { using (var connection = CreateDbConnection()) { await connection.OpenAsync(); var entry = ToSnapshotEntry(metadata, snapshot); var sqlCommand = QueryBuilder.InsertSnapshot(entry); CompleteCommand(sqlCommand, connection); var tokenSource = GetCancellationTokenSource(); try { await sqlCommand.ExecuteNonQueryAsync(tokenSource.Token); } finally { PendingOperations.Remove(tokenSource); } } }
protected override async Task SaveAsync(SnapshotMetadata metadata, object snapshot) { try { CloudBlobClient blobClient = _extension.BlobSnapshotStoreSettings.GetBlobClient(metadata.PersistenceId); CloudBlobContainer container = blobClient.GetContainerReference(_extension.BlobSnapshotStoreSettings.ContainerName); CloudBlockBlob blockBlob = container.GetBlockBlobReference(metadata.PersistenceId + "." + SnapshotVersionHelper.ToVersionKey(metadata.SequenceNr) + ".json"); var snap = JsonConvert.SerializeObject(new SelectedSnapshot(metadata, snapshot), _settings); using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(snap))) { memoryStream.Position = 0; blockBlob.Metadata.Add("SnapshotTimestamp", metadata.Timestamp.Ticks.ToString()); blockBlob.Metadata.Add("Version", SnapshotVersionHelper.ToVersionKey(metadata.SequenceNr)); await blockBlob.UploadFromStreamAsync(memoryStream); } } catch (Exception ex) { _log.Error(ex, ex.Message); } }
protected Task <SnapshotMetadata> SaveSnapshotTaskAsync(object snapshot) { if (_saveSnapshotTcsMap == null) { _saveSnapshotTcsMap = new Dictionary <long, TaskCompletionSource <SnapshotMetadata> >(); } var metadata = new SnapshotMetadata(SnapshotterId, SnapshotSequenceNr); if (_saveSnapshotTcsMap.ContainsKey(SnapshotSequenceNr)) { return(Task.FromResult(metadata)); } var tcs = new TaskCompletionSource <SnapshotMetadata>(); _saveSnapshotTcsMap.Add(SnapshotSequenceNr, tcs); SnapshotStore.Tell(new SaveSnapshot(metadata, snapshot), Self); return(tcs.Task); }
public SelectedSnapshot Map(SnapshotEntry e) { if (e == null) { return(null); } var persistenceId = e.PersistenceId; var sequenceNr = e.SequenceNr; var timestamp = e.Timestamp; var metadata = new SnapshotMetadata(persistenceId, sequenceNr, timestamp); var type = Type.GetType(e.SnapshotType, true); var serializer = _serialization.FindSerializerForType(type); var binary = e.Snapshot; var snapshot = serializer.FromBinary(binary, type); return(new SelectedSnapshot(metadata, snapshot)); }
/// <summary> /// Finds the requested snapshot in the file and returns it asynchronously. If no snapshot is found it returns null /// without waiting /// </summary> protected override Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria) { try { _loadasync++; if (_loadasync % 100000 == 0) { _log.Info("LoadAsync() - count of calls={0}", _loadasync); } // Create an empty SnapshotMetadata var metadata = new SnapshotMetadata(persistenceId, -1); // Pick a read stream to use var streamId = getReadStream(); return(RunWithStreamDispatcher(() => Load(streamId, metadata))); } catch (Exception e) { _log.Error("ERROR in LoadAsync(). Message={0}\nStacktrace={1}", e.Message, e.StackTrace); return(null); } }
protected override async Task SaveAsync(SnapshotMetadata metadata, object snapshot) { try { CloudBlobClient blobClient = _extension.BlobSnapshotStoreSettings.GetBlobClient(metadata.PersistenceId); CloudBlobContainer container = blobClient.GetContainerReference(_extension.BlobSnapshotStoreSettings.ContainerName); CloudBlockBlob blockBlob = container.GetBlockBlobReference(metadata.PersistenceId + "." + SnapshotVersionHelper.ToVersionKey(metadata.SequenceNr) + ".json"); var snap = JsonConvert.SerializeObject(new SelectedSnapshot(metadata, snapshot), _settings); using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(snap))) { memoryStream.Position = 0; blockBlob.Metadata.Add("SnapshotTimestamp", metadata.Timestamp.Ticks.ToString()); blockBlob.Metadata.Add("Version", SnapshotVersionHelper.ToVersionKey(metadata.SequenceNr)); await blockBlob.UploadFromStreamAsync(memoryStream); } } catch (Exception ex) { _log.Error(ex, ex.Message); } }
protected virtual SelectedSnapshot ReadSnapshot(DbDataReader reader) { var persistenceId = reader.GetString(0); var sequenceNr = reader.GetInt64(1); var timestamp = reader.GetDateTime(2); var metadata = new SnapshotMetadata(persistenceId, sequenceNr, timestamp); var snapshot = GetSnapshot(reader); return new SelectedSnapshot(metadata, snapshot); }
/// <summary> /// Asynchronously stores a snapshot with metadata as record in SQL table. /// </summary> protected override Task SaveAsync(SnapshotMetadata metadata, object snapshot) { var entry = ToSnapshotEntry(metadata, snapshot); var sqlCommand = QueryBuilder.InsertSnapshot(entry); CompleteCommand(sqlCommand); var tokenSource = GetCancellationTokenSource(); return sqlCommand.ExecuteNonQueryAsync(tokenSource.Token) .ContinueWith(task => { PendingOperations.Remove(tokenSource); }, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.AttachedToParent); }
protected override void Delete(SnapshotMetadata metadata) { var sqlCommand = QueryBuilder.DeleteOne(metadata.PersistenceId, metadata.SequenceNr, metadata.Timestamp); CompleteCommand(sqlCommand); sqlCommand.ExecuteNonQuery(); }
protected override Task SaveAsync(SnapshotMetadata metadata, object snapshot) { return Flop(); }
private SnapshotEntry ToSnapshotEntry(SnapshotMetadata metadata, object snapshot) { var snapshotType = snapshot.GetType(); var serializer = Context.System.Serialization.FindSerializerForType(snapshotType); var binary = serializer.ToBinary(snapshot); return new SnapshotEntry( persistenceId: metadata.PersistenceId, sequenceNr: metadata.SequenceNr, timestamp: metadata.Timestamp, snapshotType: snapshotType.QualifiedTypeName(), snapshot: binary); }
protected override void Saved(SnapshotMetadata metadata) { }
/// <summary> /// Deletes the snapshot identified by <paramref name="metadata"/>. /// </summary> protected abstract void Delete(SnapshotMetadata metadata);
/// <summary> /// Called after successful saving a snapshot. /// </summary> protected abstract void Saved(SnapshotMetadata metadata);
/// <summary> /// Deletes the snapshot identified by <paramref name="metadata"/>. /// </summary> protected abstract Task DeleteAsync(SnapshotMetadata metadata);
/// <summary> /// Asynchronously saves a snapshot. /// </summary> protected abstract Task SaveAsync(SnapshotMetadata metadata, object snapshot);
public DeleteOne(SnapshotMetadata metadata) { Metadata = metadata; }
/// <summary> /// Asynchronously stores a snapshot with metadata as record in SQL table. /// </summary> protected override async Task SaveAsync(SnapshotMetadata metadata, object snapshot) { using (var connection = CreateDbConnection()) { await connection.OpenAsync(); var entry = ToSnapshotEntry(metadata, snapshot); var sqlCommand = QueryBuilder.InsertSnapshot(entry); CompleteCommand(sqlCommand, connection); await sqlCommand.ExecuteNonQueryAsync(_pendingRequestsCancellation.Token); } }
protected override void Save(SnapshotMetadata metadata, object payload) { if (metadata.SequenceNr == 2) { var bytes = Encoding.UTF8.GetBytes("b0rk"); WithOutputStream(metadata, stream => stream.Write(bytes, 0, bytes.Length)); } else base.Save(metadata, payload); }
protected override async Task DeleteAsync(SnapshotMetadata metadata) { using (var connection = CreateDbConnection()) { await connection.OpenAsync(); var sqlCommand = QueryBuilder.DeleteOne(metadata.PersistenceId, metadata.SequenceNr, metadata.Timestamp); CompleteCommand(sqlCommand, connection); await sqlCommand.ExecuteNonQueryAsync(); } }
protected override Task DeleteAsync(SnapshotMetadata metadata) { base.DeleteAsync(metadata); // we actually delete it properly, but act as if it failed var promise = new TaskCompletionSource<object>(); promise.SetException(new ApplicationException("Failed to delete snapshot for some reason.")); return promise.Task; }
public void SnapshotStore_should_delete_a_single_snapshot_identified_by_SequenceNr_in_snapshot_metadata() { var md = Metadata[2]; md = new SnapshotMetadata(md.PersistenceId, md.SequenceNr); // don't care about timestamp for delete of a single snap var command = new DeleteSnapshot(md); var sub = CreateTestProbe(); Subscribe<DeleteSnapshot>(sub.Ref); SnapshotStore.Tell(command, _senderProbe.Ref); sub.ExpectMsg(command); _senderProbe.ExpectMsg<DeleteSnapshotSuccess>(); SnapshotStore.Tell(new LoadSnapshot(Pid, new SnapshotSelectionCriteria(md.SequenceNr), long.MaxValue), _senderProbe.Ref); _senderProbe.ExpectMsg<LoadSnapshotResult>(result => result.ToSequenceNr == long.MaxValue && result.Snapshot != null && result.Snapshot.Metadata.Equals(Metadata[1]) && result.Snapshot.Snapshot.ToString() == "s-2"); }
public virtual async Task InsertAsync(DbConnection connection, CancellationToken cancellationToken, object snapshot, SnapshotMetadata metadata) { using (var command = GetCommand(connection, InsertSnapshotSql)) using(var tx = connection.BeginTransaction()) { command.Transaction = tx; SetPersistenceIdParameter(metadata.PersistenceId, command); SetSequenceNrParameter(metadata.SequenceNr, command); SetTimestampParameter(metadata.Timestamp, command); SetManifestParameter(snapshot.GetType(), command); SetPayloadParameter(snapshot, command); await command.ExecuteNonQueryAsync(cancellationToken); tx.Commit(); } }
protected override Task DeleteAsync(SnapshotMetadata metadata) { return Flop(); }
private static SnapshotEntry ToSnapshotEntry(SnapshotMetadata metadata, object snapshot) { return new SnapshotEntry { Id = metadata.PersistenceId + "_" + metadata.SequenceNr, PersistenceId = metadata.PersistenceId, SequenceNr = metadata.SequenceNr, Snapshot = snapshot, Timestamp = metadata.Timestamp.Ticks }; }