Beispiel #1
0
        /// <summary>
        /// Asynchronously loads a snapshot.
        /// This call is protected with a circuit-breaker
        /// </summary>
        /// <param name="persistenceId">PersistenceId</param>
        /// <param name="criteria">Selection criteria</param>
        /// <returns>
        /// TBD
        /// </returns>
        protected override Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            persistenceId = IdNormalizer.Normalize(persistenceId);
            var query  = GetSnapshotQuery(persistenceId, criteria);
            var result = query
                         .Where(a => a.DocumentType == "snap")
                         .OrderByDescending(a => a.SequenceNr)
                         .ToList()//CosmosDB doesn't allow constructor invocation
                         .Select(a => {
                if (a.SerializerId.HasValue && a.Snapshot != null)
                {
                    if (a.SerializerId.Value != 1)
                    {
                        a.Snapshot = serialization.Deserialize(Convert.FromBase64String((string)a.Snapshot), a.SerializerId.Value, a.Manifest);
                    }
                    else
                    {
                        if (a.Snapshot is JObject)
                        {
                            a.Snapshot = JsonConvert.DeserializeObject(((JObject)a.Snapshot).ToString(Newtonsoft.Json.Formatting.None), Type.GetType(a.Manifest), new JsonSerializerSettings
                            {
                                TypeNameHandling = TypeNameHandling.All
                            }
                                                                       );
                        }
                    }
                }
                return(new SelectedSnapshot(new SnapshotMetadata(a.PersistenceId, a.SequenceNr,
                                                                 a.Timestamp.ToDateTime()), a.Snapshot));
            })
                         .FirstOrDefault();

            return(Task.FromResult(result));
        }
        protected override async Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            IEnumerable<CloudBlockBlob> blobs = _extension
                .BlobSnapshotStoreSettings
                .GetBlobClient(persistenceId)
                .GetContainerReference(_extension.BlobSnapshotStoreSettings.ContainerName)
                .ListBlobs(persistenceId,true,BlobListingDetails.All).Cast<CloudBlockBlob>();

            var results = blobs.OrderByDescending(t => SnapshotVersionHelper.Parse(t.Name));

            if (results.Count() > 0)
            {
                _log.Debug("Found {0} snapshots for {1}",results.Count(), persistenceId);
                foreach(CloudBlockBlob clob in results)
                {
                    if (SnapshotVersionHelper.Parse(clob.Name) <= criteria.MaxSequenceNr
                        && long.Parse(clob.Metadata["SnapshotTimestamp"]) <= criteria.MaxTimeStamp.Ticks)
                    {
                        using (var memoryStream = new MemoryStream())
                        {
                            clob.DownloadToStream(memoryStream);
                            var snapshot = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(memoryStream.ToArray()), 
                                typeof(SelectedSnapshot), _settings);
                            return (SelectedSnapshot)snapshot;
                        }
                    }
                }
                return null;
            }
            else return null;
        }
 protected override async Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
 {
     CloudTableClient tableClient = _extension.TableSnapshotStoreSettings.GetClient(persistenceId);
     CloudTable table = tableClient.GetTableReference(_extension.TableSnapshotStoreSettings.TableName);
     
     TableQuery<Snapshot> query =
                 new TableQuery<Snapshot>().Where(
                 TableQuery.CombineFilters(
                         TableQuery.GenerateFilterCondition("PartitionKey",
                             QueryComparisons.Equal, persistenceId), TableOperators.And,
                             TableQuery.GenerateFilterCondition("RowKey",
                         QueryComparisons.LessThanOrEqual, Snapshot.ToRowKey(criteria.MaxSequenceNr)))
                     );
     IEnumerable<Snapshot> results = table.ExecuteQuery(query).OrderByDescending(t=>t.SequenceNr);
     if (results.Count() > 0)
     {
         _log.Debug("Found snapshot of {0}", persistenceId);
         var result = results.First();
         
         var snapshot = JsonConvert.DeserializeObject(result.SnapshotState, typeof(SelectedSnapshot),_settings);
         if (((SelectedSnapshot)snapshot).Metadata.Timestamp > criteria.MaxTimeStamp)
             return null;
         return (SelectedSnapshot)snapshot;
     }
     else return null;
 }
 protected override Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
 {
     return(Equals(criteria, SnapshotSelectionCriteria.Latest)
         ? GetLatestSnapshot(persistenceId)
             : (Equals(criteria, SnapshotSelectionCriteria.None)
             ? null : GetSnapShotByCriteria(persistenceId, criteria)));
 }
        protected override Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {

            // Create a Query with dynamic parameters
            string N1QLQueryString = "select `" + _CBBucket.Name + "`.* from `" + _CBBucket.Name + "` where DocumentType = 'SnapshotEntry' AND PersistenceId = $PersistenceId ";

            IQueryRequest N1QLQueryRequest = new QueryRequest()
                    .AddNamedParameter("PersistenceId", persistenceId);

            string N1QLQueryOrderByClauseString = "ORDER BY SequenceNr DESC";
            
            if (criteria.MaxSequenceNr > 0 && criteria.MaxSequenceNr < long.MaxValue)
            {
                N1QLQueryString += "AND SequenceNr <= $limit ";
                N1QLQueryOrderByClauseString = "ORDER BY SequenceNr DESC,";
                N1QLQueryRequest.AddNamedParameter("limit",criteria.MaxSequenceNr);
            }

            if (criteria.MaxTimeStamp != DateTime.MinValue && criteria.MaxTimeStamp != DateTime.MaxValue)
            {
                N1QLQueryString += " AND Timestamp <= $timelimit ";
                N1QLQueryOrderByClauseString = "ORDER BY Timestamp DESC,";
                N1QLQueryRequest.AddNamedParameter("timelimit", criteria.MaxTimeStamp.Ticks.ToString());
            }

            N1QLQueryString += N1QLQueryOrderByClauseString.TrimEnd(',') + " LIMIT 1"; 

            N1QLQueryRequest.Statement(N1QLQueryString).AdHoc(false);

            return taskLoadAsync(N1QLQueryRequest);
                

        }
        protected override async Task <SelectedSnapshot> LoadAsync(string persistenceId,
                                                                   SnapshotSelectionCriteria criteria)
        {
            if (criteria.Equals(SnapshotSelectionCriteria.None))
            {
                return(null);
            }

            var streamName = GetStreamName(persistenceId);


            if (!criteria.Equals(SnapshotSelectionCriteria.Latest))
            {
                var result = await FindSnapshot(streamName, criteria.MaxSequenceNr, criteria.MaxTimeStamp);

                return(result.Snapshot);
            }

            var slice = await _conn.ReadStreamEventsBackwardAsync(streamName, StreamPosition.End, 1, false);

            if (slice == null || slice.Status != SliceReadStatus.Success || !slice.Events.Any())
            {
                return(null);
            }

            return(slice.Events.Select(_snapshotAdapter.Adapt).First());
        }
Beispiel #7
0
        protected override Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            // Create a Query with dynamic parameters
            string N1QLQueryString = "select `" + _CBBucket.Name + "`.* from `" + _CBBucket.Name + "` where DocumentType = 'SnapshotEntry' AND PersistenceId = $PersistenceId ";

            IQueryRequest N1QLQueryRequest = new QueryRequest()
                                             .AddNamedParameter("PersistenceId", persistenceId);

            string N1QLQueryOrderByClauseString = "ORDER BY SequenceNr DESC";

            if (criteria.MaxSequenceNr > 0 && criteria.MaxSequenceNr < long.MaxValue)
            {
                N1QLQueryString += "AND SequenceNr <= $limit ";
                N1QLQueryOrderByClauseString = "ORDER BY SequenceNr DESC,";
                N1QLQueryRequest.AddNamedParameter("limit", criteria.MaxSequenceNr);
            }

            if (criteria.MaxTimeStamp != DateTime.MinValue && criteria.MaxTimeStamp != DateTime.MaxValue)
            {
                N1QLQueryString += " AND Timestamp <= $timelimit ";
                N1QLQueryOrderByClauseString = "ORDER BY Timestamp DESC,";
                N1QLQueryRequest.AddNamedParameter("timelimit", criteria.MaxTimeStamp.Ticks.ToString());
            }

            N1QLQueryString += N1QLQueryOrderByClauseString.TrimEnd(',') + " LIMIT 1";

            N1QLQueryRequest.Statement(N1QLQueryString).AdHoc(false);

            return(taskLoadAsync(N1QLQueryRequest));
        }
Beispiel #8
0
        protected override Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var filter = CreateRangeFilter(persistenceId, criteria);


            return(Task.Run(() => { _snapshotCollection.RemoveAll(x => filter(x)); }));
        }
 /// <summary>
 /// TBD
 /// </summary>
 /// <param name="persistenceId">TBD</param>
 /// <param name="criteria">TBD</param>
 /// <returns>TBD</returns>
 protected override async Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
 {
     foreach (var metadata in GetSnapshotMetadata(persistenceId, criteria))
     {
         await DeleteAsync(metadata);
     }
 }
Beispiel #10
0
 public Recover(SnapshotSelectionCriteria fromSnapshot, long toSequenceNr = long.MaxValue,
                long replayMax = long.MaxValue)
 {
     FromSnapshot = fromSnapshot;
     ToSequenceNr = toSequenceNr;
     ReplayMax    = replayMax;
 }
Beispiel #11
0
        protected async override Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            ServiceEventSource.Current.Message($"Entering ServiceFabricSnapshotStore.{nameof(DeleteAsync)} PersistenceId: {persistenceId} ");

            if ((criteria.MaxSequenceNr > 0 && criteria.MaxSequenceNr < long.MaxValue) &&
                (criteria.MaxTimeStamp != DateTime.MinValue && criteria.MaxTimeStamp != DateTime.MaxValue))
            {
                using (var tx = this.StateManager.CreateTransaction())
                {
                    var snapshots = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, SnapshotEntry> >(persistenceId);

                    long FirstSequenceNumber = 0;
                    for (long i = 0; i < criteria.MaxSequenceNr; i++)
                    {
                        var result = await snapshots.TryGetValueAsync(tx, $"{persistenceId}_{i}");

                        var snapShot = result.HasValue ? result.Value : null;
                        if (snapShot.Timestamp > criteria.MaxTimeStamp.Ticks)
                        {
                            FirstSequenceNumber = i;
                            await snapshots.TryRemoveAsync(tx, $"{persistenceId}_{i}");
                        }
                    }

                    await tx.CommitAsync();
                }
            }
        }
Beispiel #12
0
        protected override Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var filter = CreateRangeFilter(persistenceId, criteria);

            Snapshots.RemoveAll(x => filter(x));
            return(TaskEx.Completed);
        }
Beispiel #13
0
        protected override async Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            switch (criteria.MaxSequenceNr)
            {
            case long.MaxValue when criteria.MaxTimeStamp == DateTime.MaxValue:
                await _dao.DeleteAllSnapshots(persistenceId);

                break;

            case long.MaxValue:
                await _dao.DeleteUpToMaxTimestamp(persistenceId,
                                                  criteria
                                                  .MaxTimeStamp);

                break;

            default:
            {
                if (criteria.MaxTimeStamp == DateTime.MaxValue)
                {
                    await _dao.DeleteUpToMaxSequenceNr(persistenceId,
                                                       criteria.MaxSequenceNr);
                }
                else
                {
                    await _dao
                    .DeleteUpToMaxSequenceNrAndMaxTimestamp(
                        persistenceId, criteria.MaxSequenceNr,
                        criteria
                        .MaxTimeStamp);
                }
                break;
            }
            }
        }
        protected override async Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var filter = Filter.And(
                Filter.HasAncestor(RootKey(persistenceId)),
                Filter.GreaterThanOrEqual(SnapshotFields.SequenceNr, criteria.MinSequenceNr),
                Filter.LessThanOrEqual(SnapshotFields.SequenceNr, criteria.MaxSequenceNr)
                //,Filter.LessThanOrEqual(SnapshotFields.Timestamp, criteria.MaxTimeStamp.Ticks)
                );
            //            if (criteria.MinTimestamp.HasValue)
            //            {
            //                filter = Filter.And(filter,
            //                    Filter.GreaterThanOrEqual(SnapshotFields.Timestamp, criteria.MinTimestamp.Value.Ticks)
            //                );
            //            }

            Query query = new Query(_snapshotKind)
            {
                Filter = filter,
                Order  = { { JournalFields.SequenceNr, PropertyOrder.Types.Direction.Ascending } }
                //,Limit = (int) max
            };

            var results = await _db.RunQueryAsync(query).ConfigureAwait(false);

            var timestampFiltered =
                results.Entities?.Where(
                    e => e[SnapshotFields.SequenceNr].IntegerValue <= criteria.MaxSequenceNr &&
                    e[SnapshotFields.SequenceNr].IntegerValue >= criteria.MinSequenceNr &&
                    e[SnapshotFields.Timestamp].IntegerValue <= criteria.MaxTimeStamp.Ticks &&
                    e[SnapshotFields.Timestamp].IntegerValue >= criteria.MinTimestamp?.Ticks
                    );
            await _db.DeleteAsync(timestampFiltered);

            await CheckDeleteRootsnapshot(persistenceId, criteria.MaxSequenceNr, criteria.MaxTimeStamp.Ticks);
        }
Beispiel #15
0
        protected override Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var proxy = ActorProxy.Create <IServiceFabricSnapshotStore>(new ActorId(persistenceId), _servicefabricServiceUri);


            return(Task.FromResult(Map(proxy.SelectSnapshotAsync(criteria.MaxSequenceNr, criteria.MaxTimeStamp).Result)));
        }
 protected override void Delete(string persistenceId, SnapshotSelectionCriteria criteria)
 {
     foreach (var metadata in GetSnapshotMetadata(persistenceId, criteria))
     {
         Delete(metadata);
     }
 }
 protected override async Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
 {
     try
     {
         CloudTableClient      tableClient = _extension.TableSnapshotStoreSettings.GetClient(persistenceId);
         CloudTable            table       = tableClient.GetTableReference(_extension.TableSnapshotStoreSettings.TableName);
         TableQuery <Snapshot> query       =
             new TableQuery <Snapshot>().Where(
                 TableQuery.CombineFilters(
                     TableQuery.GenerateFilterCondition("PartitionKey",
                                                        QueryComparisons.Equal, persistenceId), TableOperators.And,
                     TableQuery.GenerateFilterCondition("RowKey",
                                                        QueryComparisons.LessThanOrEqual, Snapshot.ToRowKey(criteria.MaxSequenceNr)))
                 );
         IEnumerable <Snapshot> results = table.ExecuteQuery(query).OrderByDescending(t => t.SequenceNr);
         if (results.Count() > 0)
         {
             TableBatchOperation batchOperation = new TableBatchOperation();
             foreach (Snapshot s in results)
             {
                 batchOperation.Delete(s);
             }
             table.ExecuteBatch(batchOperation);
         }
     }
     catch (Exception ex)
     {
         _log.Error(ex, ex.Message);
         throw;
     }
 }
 protected override Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
 {
     // Heurisitics: take 3 latest snapshots
     //TODO: convert 3 to configurable value
     var metas = GetSnapshotMetadata(persistenceId, criteria);
     return Task.FromResult(Load(metas, 3));
 }
Beispiel #19
0
        private static bool FilterBlobTimestamp(SnapshotSelectionCriteria criteria, CloudBlob x)
        {
            var ticks = FetchBlobTimestamp(x);

            return(ticks <= criteria.MaxTimeStamp.Ticks &&
                   (!criteria.MinTimestamp.HasValue || criteria.MinTimestamp.Value.Ticks >= ticks));
        }
Beispiel #20
0
        public void SnapshotStore_should_not_delete_snapshots_with_non_matching_upper_timestamp_bounds()
        {
            var snapshotMetadata = _metadata[3];
            var criteria         = new SnapshotSelectionCriteria(snapshotMetadata.SequenceNr,
                                                                 snapshotMetadata.Timestamp.Subtract(TimeSpan.FromTicks(1L)), 0L, new DateTime?());
            var message   = new DeleteSnapshots(Pid, criteria);
            var testProbe = CreateTestProbe();

            Subscribe <DeleteSnapshots>(testProbe.Ref);
            SnapshotStore.Tell(message, _senderProbe.Ref);
            testProbe.ExpectMsg(message, new TimeSpan?());
            _senderProbe.ExpectMsg <DeleteSnapshotsSuccess>(m => m.Criteria.Equals(criteria), new TimeSpan?());
            SnapshotStore.Tell(
                new LoadSnapshot(Pid,
                                 new SnapshotSelectionCriteria(snapshotMetadata.SequenceNr, snapshotMetadata.Timestamp, 0L,
                                                               new DateTime?()), long.MaxValue), _senderProbe.Ref);
            _senderProbe.ExpectMsg((Predicate <LoadSnapshotResult>)(result =>
            {
                if (result.ToSequenceNr == long.MaxValue && result.Snapshot != null &&
                    result.Snapshot.Metadata.Equals(_metadata[3]))
                {
                    return(result.Snapshot.Snapshot.ToString() == "s-4");
                }
                return(false);
            }), new TimeSpan?());
        }
Beispiel #21
0
 protected override void Delete(string persistenceId, SnapshotSelectionCriteria criteria)
 {
     foreach (var metadata in GetSnapshotMetadata(persistenceId, criteria))
     {
         Delete(metadata);
     }
 }
Beispiel #22
0
        protected override async Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var filter = RowFilters.Chain
                         (
                RowFilters.ColumnQualifierExact(SnapshotMetaDataColumnQualifier),
                // this filter ensures that we only download snapshot metadata
                RowFilters.TimestampRange(
                    ToUtc(criteria.MinTimestamp),
                    ToUtc(criteria.MaxTimeStamp)?.AddMilliseconds(1)
                    // add a milliseconds since the upper bound is exclusive
                    ),
                RowFilters.CellsPerColumnLimit(1)
                         );

            var readRowsRequest = new ReadRowsRequest
            {
                TableNameAsTableName = _tableName,
                Filter = filter,
                Rows   = GetRowSet(persistenceId, criteria.MinSequenceNr, criteria.MaxSequenceNr)
            };

            var deleteMutations = await _bigtableClient
                                  .ReadRows(readRowsRequest)
                                  .Select(SnapshotMetadataFromBigtableRow)
                                  .Where(metadata => SatisfiesTimestampCriteria(criteria, metadata))
                                  .Select(metadata => Mutations.CreateEntry(GetRowKey(persistenceId, metadata.SequenceNr), Mutations.DeleteFromRow()))
                                  .ToList()
                                  .ConfigureAwait(false);

            if (deleteMutations.Count > 0)
            {
                await _bigtableClient.MutateRowsAsync(_tableName, deleteMutations).ConfigureAwait(false);
            }
        }
        protected override void Delete(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var sqlCommand = QueryBuilder.DeleteMany(persistenceId, criteria.MaxSequenceNr, criteria.MaxTimeStamp);

            CompleteCommand(sqlCommand);

            sqlCommand.ExecuteNonQuery();
        }
            protected override Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
            {

                var proxy = ActorProxy.Create<IServiceFabricSnapshotStore>(new ActorId(persistenceId), _servicefabricServiceUri);


                return Task.FromResult(Map(proxy.SelectSnapshotAsync(criteria.MaxSequenceNr, criteria.MaxTimeStamp).Result));
            }
Beispiel #25
0
            protected override Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
            {
                base.DeleteAsync(persistenceId, criteria); // we actually delete it properly, but act as if it failed
                var promise = new TaskCompletionSource <object>();

                promise.SetException(new InvalidOperationException("Failed to delete snapshot for some reason."));
                return(promise.Task);
            }
Beispiel #26
0
        protected override Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            // Heurisitics: take 3 latest snapshots
            //TODO: convert 3 to configurable value
            var metas = GetSnapshotMetadata(persistenceId, criteria);

            return(Task.FromResult(Load(metas, 3)));
        }
Beispiel #27
0
        protected override Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var filter = CreateRangeFilter(persistenceId, criteria);


            var snapshot = Snapshots.Where(filter).OrderByDescending(x => x.SequenceNr).Take(1).Select(x => ToSelectedSnapshot(x)).FirstOrDefault();

            return(Task.FromResult(snapshot));
        }
Beispiel #28
0
            public Task InterceptAsync(string persistenceId, SnapshotSelectionCriteria criteria)
            {
                CalledAt      = DateTime.Now;
                WasCalled     = true;
                PersistenceId = persistenceId;
                Criteria      = criteria;

                return(Task.CompletedTask);
            }
Beispiel #29
0
            public async Task InterceptAsync(string persistenceId, SnapshotSelectionCriteria criteria)
            {
                var result = await _predicate(persistenceId, criteria);

                if ((_negate && !result) || (!_negate && result))
                {
                    await _next.InterceptAsync(persistenceId, criteria);
                }
            }
Beispiel #30
0
        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="persistenceId">TBD</param>
        /// <param name="criteria">TBD</param>
        /// <returns>TBD</returns>
        protected override async Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            using (var connection = CreateDbConnection())
            {
                await connection.OpenAsync();

                await QueryExecutor.DeleteBatchAsync(connection, _pendingRequestsCancellation.Token, persistenceId, criteria.MaxSequenceNr, criteria.MaxTimeStamp);
            }
        }
        protected override Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var filter = CreateRangeFilter(persistenceId, criteria);

            return
                (_collection
                 .Find(filter)
                 .Project(x => ToSelectedSnapshot(x))
                 .FirstOrDefaultAsync());
        }
        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;
        }
        protected override Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var filter = CreateRangeFilter(persistenceId, criteria);

            return
                _collection
                    .Find(filter)
                    .Project(x => ToSelectedSnapshot(x))
                    .FirstOrDefaultAsync();
        }
        protected override Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var filter = CreateRangeFilter(persistenceId, criteria);

            return
                _snapshotCollection.Value
                    .Find(filter)
                    .SortByDescending(x => x.SequenceNr)
                    .Limit(1)
                    .Project(x => ToSelectedSnapshot(x))
                    .FirstOrDefaultAsync();
        }
Beispiel #35
0
        /// <summary>
        /// Deletes all snapshots matching provided <paramref name="criteria" />.
        /// This call is protected with a circuit-breaker
        /// </summary>
        /// <param name="persistenceId">persistenceId</param>
        /// <param name="criteria">Criteria</param>
        /// <returns>
        /// TBD
        /// </returns>
        protected override async Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var query       = GetSnapshotQuery(persistenceId, criteria);
            var documents   = query.ToList();
            var deleteTasks = documents.Select(async a =>
            {
                await documentClient.Value.DeleteDocumentAsync(
                    UriFactory.CreateDocumentUri(documentDbDatabase.Value.Id, snapShotCollection.Value.Id, a.Id));
            });

            await Task.WhenAll(deleteTasks.ToArray());
        }
Beispiel #36
0
        /// <summary>
        /// Asynchronously loads a snapshot.
        /// This call is protected with a circuit-breaker
        /// </summary>
        /// <param name="persistenceId">PersistenceId</param>
        /// <param name="criteria">Selection criteria</param>
        /// <returns>
        /// TBD
        /// </returns>
        protected override Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var query  = GetSnapshotQuery(persistenceId, criteria);
            var result = query
                         .OrderByDescending(a => a.SequenceNr)
                         .ToList()//DocumentDb doesnt allow constructor invocation
                         .Select(a => new SelectedSnapshot(new SnapshotMetadata(a.PersistenceId, a.SequenceNr,
                                                                                a.Timestamp.ToDateTime()), a.Snapshot))
                         .FirstOrDefault();

            return(Task.FromResult(result));
        }
        protected override Task <SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var filter = CreateRangeFilter(persistenceId, criteria);

            return
                (_snapshotCollection.Value
                 .Find(filter)
                 .SortByDescending(x => x.SequenceNr)
                 .Limit(1)
                 .Project(x => ToSelectedSnapshot(x))
                 .FirstOrDefaultAsync());
        }
Beispiel #38
0
        protected override Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            _log.Debug("DeleteAsync() -persistenceId: {0}", persistenceId);

            // Create an empty SnapshotMetadata
            var metadata = new SnapshotMetadata(persistenceId, -1);

            return(RunWithStreamDispatcher(() => {
                Delete(metadata);
                return new object();
            }));
        }
Beispiel #39
0
        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.GenerateIfExistsCondition(),
                                                             GenerateOptions(), new OperationContext(), cts.Token);

                        var snapshot = _serialization.SnapshotFromBytes(memoryStream.ToArray());
                        return(new SelectedSnapshot(new SnapshotMetadata(persistenceId, FetchBlobSeqNo(filtered)),
                                                    snapshot.Data));
                    }
            }

            // 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);
        }
        private static FilterDefinition<SnapshotEntry> CreateRangeFilter(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var builder = Builders<SnapshotEntry>.Filter;
            var filter = builder.Eq(x => x.PersistenceId, persistenceId);

            if (criteria.MaxSequenceNr > 0 && criteria.MaxSequenceNr < long.MaxValue)
                filter &= builder.Lte(x => x.SequenceNr, criteria.MaxSequenceNr);

            if (criteria.MaxTimeStamp != DateTime.MinValue && criteria.MaxTimeStamp != DateTime.MaxValue)
                filter &= builder.Lte(x => x.Timestamp, criteria.MaxTimeStamp.Ticks);

            return filter;
        }
        /// <summary>
        /// Asynchronously loads snapshot with the highest sequence number for a persistent actor/view matching specified criteria.
        /// </summary>
        protected override async Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            using (var connection = CreateDbConnection())
            {
                await connection.OpenAsync();

                var sqlCommand = QueryBuilder.SelectSnapshot(persistenceId, criteria.MaxSequenceNr, criteria.MaxTimeStamp);
                CompleteCommand(sqlCommand, connection);
                
                var reader = await sqlCommand.ExecuteReaderAsync(_pendingRequestsCancellation.Token);
                try
                {
                    return reader.Read() ? QueryMapper.Map(reader) : null;
                }
                finally
                {
                    reader.Close();
                }
            }
        }
        /// <summary>
        /// Asynchronously loads snapshot with the highest sequence number for a persistent actor/view matching specified criteria.
        /// </summary>
        protected override Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var sqlCommand = QueryBuilder.SelectSnapshot(persistenceId, criteria.MaxSequenceNr, criteria.MaxTimeStamp);
            CompleteCommand(sqlCommand);

            var tokenSource = GetCancellationTokenSource();
            return sqlCommand
                .ExecuteReaderAsync(tokenSource.Token)
                .ContinueWith(task =>
                {
                    var reader = task.Result;
                    try
                    {
                        return reader.Read() ? QueryMapper.Map(reader) : null;
                    }
                    finally
                    {
                        PendingOperations.Remove(tokenSource);
                        reader.Close();
                    }
                }, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.AttachedToParent);
        }
        protected override async Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var connection = await GetConnection();
            var streamName = GetStreamName(persistenceId);
            var requestedSnapVersion = (int)criteria.MaxSequenceNr;
            StreamEventsSlice slice = null;
            if (criteria.MaxSequenceNr == long.MaxValue)
            {
                requestedSnapVersion = StreamPosition.End;
                slice = await connection.ReadStreamEventsBackwardAsync(streamName, requestedSnapVersion, 1, false);
            }
            else
            {
                slice = await connection.ReadStreamEventsBackwardAsync(streamName, StreamPosition.End, requestedSnapVersion, false);
            }

            if (slice.Status == SliceReadStatus.StreamNotFound)
            {
                await connection.SetStreamMetadataAsync(streamName, ExpectedVersion.Any, StreamMetadata.Data);
                return null;
            }

            if (slice.Events.Any())
            {
                _log.Debug("Found snapshot of {0}", persistenceId);
                if (requestedSnapVersion == StreamPosition.End)
                {
                    var @event = slice.Events.First().OriginalEvent;
                    return (SelectedSnapshot)_serializer.FromBinary(@event.Data, typeof(SelectedSnapshot));
                }
                else
                {
                    var @event = slice.Events.Where(t => t.OriginalEvent.EventNumber == requestedSnapVersion).First().OriginalEvent;
                    return (SelectedSnapshot)_serializer.FromBinary(@event.Data, typeof(SelectedSnapshot));
                }
            }

            return null;
        }
 protected override async Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
 {
     await repository.Delete<SnapshotEntry>(persistenceId, criteria.MaxSequenceNr, criteria.MaxTimeStamp);
 }
        protected override async Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            using (var connection = CreateDbConnection())
            {
                await connection.OpenAsync();
                var sqlCommand = QueryBuilder.DeleteMany(persistenceId, criteria.MaxSequenceNr, criteria.MaxTimeStamp);
                CompleteCommand(sqlCommand, connection);

                await sqlCommand.ExecuteNonQueryAsync();
            }
        }
Beispiel #46
0
 protected override Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria)
 {
     return Task.FromResult((SelectedSnapshot)null);
 }
        private IEnumerable<SnapshotMetadata> GetSnapshotMetadata(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var snapshots = _snapshotDirectory
                .EnumerateFiles("snapshot-" + persistenceId + "-*", SearchOption.TopDirectoryOnly)
                .Select(ExtractSnapshotMetadata)
                .Where(metadata => metadata != null && criteria.IsMatch(metadata) && !_saving.Contains(metadata));

            return snapshots;    // guaranteed to be not null in previous constraint
        }
            protected override void Delete(string persistenceId, SnapshotSelectionCriteria criteria)
            {
                var proxy = ActorProxy.Create<IServiceFabricSnapshotStore>(new ActorId(persistenceId), _servicefabricServiceUri);

                proxy.DeleteSnapshotManyAsync(criteria.MaxSequenceNr, criteria.MaxTimeStamp);
            }
Beispiel #49
0
        public void SnapshotStore_should_not_delete_snapshots_with_non_matching_upper_timestamp_bounds()
        {
            var md = Metadata[3];
            var criteria = new SnapshotSelectionCriteria(md.SequenceNr, md.Timestamp.Subtract(TimeSpan.FromTicks(1)));
            var command = new DeleteSnapshots(Pid, criteria);
            var sub = CreateTestProbe();

            Subscribe<DeleteSnapshots>(sub.Ref);
            SnapshotStore.Tell(command, _senderProbe.Ref);
            sub.ExpectMsg(command);
            _senderProbe.ExpectMsg<DeleteSnapshotsSuccess>(m => m.Criteria.Equals(criteria));

            SnapshotStore.Tell(new LoadSnapshot(Pid, new SnapshotSelectionCriteria(md.SequenceNr, md.Timestamp), long.MaxValue), _senderProbe.Ref);
            _senderProbe.ExpectMsg<LoadSnapshotResult>(result =>
                result.ToSequenceNr == long.MaxValue
                && result.Snapshot != null
                && result.Snapshot.Metadata.Equals(Metadata[3])
                && result.Snapshot.Snapshot.ToString() == "s-4");
        }
Beispiel #50
0
 public DeleteSnapshots(SnapshotSelectionCriteria criteria)
 {
     Criteria = criteria;
 }
Beispiel #51
0
        public void PersistentActor_with_a_failing_snapshot_should_receive_failure_message_when_bulk_deleting_snapshots_fails()
        {
            var pref = Sys.ActorOf(Props.Create(() => new DeleteSnapshotTestActor(Name, TestActor)));

            ExpectMsg<RecoveryCompleted>();
            pref.Tell(new Cmd("hello"));
            ExpectMsg(1L);
            pref.Tell(new Cmd("hola"));
            ExpectMsg(2L);
            var criteria = new SnapshotSelectionCriteria(10);
            pref.Tell(new DeleteSnapshots(criteria));
            ExpectMsg<DeleteSnapshotsFailure>(m => m.Criteria.Equals(criteria) &&
                                          m.Cause.Message.Contains("Failed to delete"));
        }
Beispiel #52
0
 /// <summary>
 /// Asynchronously loads a snapshot.
 /// </summary>
 protected abstract Task<SelectedSnapshot> LoadAsync(string persistenceId, SnapshotSelectionCriteria criteria);
Beispiel #53
0
 /// <summary>
 /// Deletes all snapshots matching provided <paramref name="criteria"/>.
 /// </summary>
 protected abstract Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria);
 protected override void Delete(string persistenceId, SnapshotSelectionCriteria criteria)
 {}
Beispiel #55
0
 public Recover(SnapshotSelectionCriteria fromSnapshot, long toSequenceNr = long.MaxValue, long replayMax = long.MaxValue)
 {
     FromSnapshot = fromSnapshot;
     ToSequenceNr = toSequenceNr;
     ReplayMax = replayMax;
 }
Beispiel #56
0
 /// <summary>
 /// Deletes all snapshots matching provided <paramref name="criteria"/>.
 /// </summary>
 protected abstract void Delete(string persistenceId, SnapshotSelectionCriteria criteria);
Beispiel #57
0
 protected override Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
 {
     base.DeleteAsync(persistenceId, criteria); // 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;
 }
        protected override Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var filter = CreateRangeFilter(persistenceId, criteria);

            return _snapshotCollection.Value.DeleteManyAsync(filter);
        }
Beispiel #59
0
 protected override Task DeleteAsync(string persistenceId, SnapshotSelectionCriteria criteria)
 {
     return Flop();
 }
Beispiel #60
0
        protected override void Delete(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var sqlCommand = QueryBuilder.DeleteMany(persistenceId, criteria.MaxSequenceNr, criteria.MaxTimeStamp);
            CompleteCommand(sqlCommand);

            sqlCommand.ExecuteNonQuery();
        }