Пример #1
0
        public async Task BasicCriteriaTest()
        {
            using (var store = GetDocumentStore())
                using (var subscriptionManager = new DocumentSubscriptions(store))
                {
                    await CreateDocuments(store, 1);

                    var lastEtag = store.GetLastWrittenEtag() ?? 0;
                    await CreateDocuments(store, 5);

                    var subscriptionCriteria = new SubscriptionCriteria
                    {
                        Collection       = "Things",
                        FilterJavaScript = " return this.Name == 'ThingNo3'",
                    };
                    var subsId = subscriptionManager.Create(subscriptionCriteria, lastEtag);
                    using (var subscription = subscriptionManager.Open <Thing>(new SubscriptionConnectionOptions()
                    {
                        SubscriptionId = subsId
                    }))
                    {
                        var list = new BlockingCollection <Thing>();
                        subscription.Subscribe(x =>
                        {
                            list.Add(x);
                        });
                        await subscription.StartAsync();

                        Thing thing;
                        Assert.True(list.TryTake(out thing, 5000));
                        Assert.Equal("ThingNo3", thing.Name);
                        Assert.False(list.TryTake(out thing, 50));
                    }
                }
        }
Пример #2
0
        public long CreateSubscription(SubscriptionCriteria criteria)
        {
            long id = -1;

            using (Database.IdentityLock.Lock())
            {
                Database.TransactionalStorage.Batch(accessor =>
                {
                    id = accessor.General.GetNextIdentityValue(Constants.RavenSubscriptionsPrefix);

                    try
                    {
                        if (criteria.StartEtag == null || criteria.StartEtag == Etag.Empty)
                        {
                            TryFigureOutFirstEtagForSubscription(criteria);
                        }
                    }
                    catch (Exception e)
                    {
                        Log.InfoException("Could not figure out start etag for subscription automatically", e);
                    }

                    var config = new SubscriptionConfig
                    {
                        SubscriptionId = id,
                        Criteria       = criteria,
                        AckEtag        = criteria.StartEtag ?? Etag.Empty,
                    };

                    SaveSubscriptionConfig(id, config);
                });
            }

            return(id);
        }
Пример #3
0
        public async Task CreateSubscriptions()
        {
            var store = GetDocumentStore();

            var subscriptionCriteria = new SubscriptionCriteria
            {
                Collection = "People",
            };
            var subsId = await store.AsyncSubscriptions.CreateAsync(subscriptionCriteria);

            var subscriptionCriteria2 = new SubscriptionCriteria
            {
                Collection = "Users",
            };
            var subsId2 = await store.AsyncSubscriptions.CreateAsync(subscriptionCriteria2);

            var subscriptionsConfig = await store.AsyncSubscriptions.GetSubscriptionsAsync(0, 10);

            Assert.Equal(2, subscriptionsConfig.Count);
            Assert.Equal(subscriptionCriteria.Collection, subscriptionsConfig[0].Criteria.Collection);
            Assert.Equal(subscriptionCriteria2.FilterJavaScript, subscriptionsConfig[1].Criteria.FilterJavaScript);
            Assert.Equal(0, subscriptionsConfig[0].AckEtag);
            Assert.Equal(subsId2, subscriptionsConfig[1].SubscriptionId);

            // TODO fix delete handler on server side

            /*await store.AsyncSubscriptions.DeleteAsync(subsId);
             * subscriptionsConfig = await store.AsyncSubscriptions.GetSubscriptionsAsync(0, 10);
             * Assert.Equal(1, subscriptionsConfig.Count);*/
        }
Пример #4
0
        /// <summary>
        /// Create a new filter within the node. This filter can be used to poll for new messages that match the set of criteria
        /// </summary>
        /// <param name="filters">Message filters</param>
        /// <param name="ctoken">cancellation token</param>
        /// <returns>filter identifier</returns>
        public async Task <string> CreateNewMessageFilter(SubscriptionCriteria filters, CancellationToken ctoken)
        {
            JArray jarrayObj = new JArray();
            var    outObject = (JObject)JToken.FromObject(filters);

            jarrayObj.Add(outObject);
            return(await BuildAndSendRequest("shh_newMessageFilter", jarrayObj, string.Empty, ctoken));
        }
Пример #5
0
        private SubscriptionPatchDocument SetupFilterScript(SubscriptionCriteria criteria)
        {
            SubscriptionPatchDocument patch = null;

            if (string.IsNullOrWhiteSpace(criteria.FilterJavaScript) == false)
            {
                patch = new SubscriptionPatchDocument(TcpConnection.DocumentDatabase, criteria.FilterJavaScript);
            }
            return(patch);
        }
Пример #6
0
        /// <summary>
        /// Creates and registers a new subscription to receive notifications for inbound whisper messages.
        /// Returns the ID of the newly created subscription.
        /// Either symKeyID or privateKeyID must be present. Can not be both
        /// </summary>
        /// <param name="filters">message filters</param>
        /// <param name="id">identifier of function call. In case of Whisper must contain the value "messages"
        /// This might be the case in some very rare cases, e.g. if you intend to communicate to MailServers, etc</param>
        /// <param name="ctoken">cancellation token</param>
        /// <returns>subscription id</returns>
        public async Task <string> Subscribe(SubscriptionCriteria filters, CancellationToken ctoken, string id = "messages")
        {
            JArray jarrayObj = new JArray();

            jarrayObj.Add(id);
            var outObject = (JObject)JToken.FromObject(filters);

            jarrayObj.Add(outObject);
            return(await BuildAndSendRequest("shh_subscribe", jarrayObj, string.Empty, ctoken));
        }
Пример #7
0
        private void TryFigureOutFirstEtagForSubscription(SubscriptionCriteria criteria)
        {
            if (criteria.KeyStartsWith != null ||
                criteria.BelongsToAnyCollection == null ||
                criteria.BelongsToAnyCollection.Length == 0)
            {
                return;
            }


            if (!Database.IndexStorage.HasIndex(Constants.DocumentsByEntityNameIndex))
            {
                return;
            }

            var indexDefinition = Database.IndexStorage.GetIndexInstance(Constants.DocumentsByEntityNameIndex);

            var lastEtag = indexDefinition.GetLastEtagFromStats();

            var results = Database.Queries.Query(Constants.DocumentsByEntityNameIndex, new IndexQuery
            {
                SortedFields = new[] { new SortedField("LastModifiedTicks") },
                Query        = string.Join(" OR ", criteria.BelongsToAnyCollection.Select(collection => " Tag:[[" + collection + "]] ")),
                PageSize     = 128
            }, CancellationToken.None);

            var indexTimestamp = results.IndexTimestamp;

            if (results.Results.Count == 0)
            {
                criteria.StartEtag = lastEtag;
                return;
            }

            foreach (var document in results.Results)
            {
                var metadata     = document.Value <RavenJObject>(Constants.Metadata);
                var lastModified = metadata.Value <DateTime>(Constants.RavenLastModified);

                if (lastModified > indexTimestamp)
                {
                    continue;
                }

                var earliestEtag = new Etag(metadata.Value <string>("@etag"));

                if (earliestEtag.Changes > 0)
                {
                    criteria.StartEtag = earliestEtag.DecrementBy(1);
                }
                return;
            }
        }
Пример #8
0
        private static bool MatchCriteria(SubscriptionCriteria criteria, JsonDocument doc)
        {
            if (criteria.BelongsToAnyCollection != null &&
                criteria.BelongsToAnyCollection.Contains(doc.Metadata.Value <string>(Constants.RavenEntityName), StringComparer.InvariantCultureIgnoreCase) == false)
            {
                return(false);
            }

            if (criteria.KeyStartsWith != null && doc.Key.StartsWith(criteria.KeyStartsWith) == false)
            {
                return(false);
            }

            if (criteria.PropertiesMatch != null)
            {
                foreach (var match in criteria.PropertiesMatch)
                {
                    var tokens = doc.DataAsJson.SelectTokenWithRavenSyntaxReturningFlatStructure(match.Key).Select(x => x.Item1).ToArray();

                    foreach (var curVal in tokens)
                    {
                        if (RavenJToken.DeepEquals(curVal, match.Value) == false)
                        {
                            return(false);
                        }
                    }

                    if (tokens.Length == 0)
                    {
                        return(false);
                    }
                }
            }

            if (criteria.PropertiesNotMatch != null)
            {
                foreach (var match in criteria.PropertiesNotMatch)
                {
                    var tokens = doc.DataAsJson.SelectTokenWithRavenSyntaxReturningFlatStructure(match.Key).Select(x => x.Item1).ToArray();

                    foreach (var curVal in tokens)
                    {
                        if (RavenJToken.DeepEquals(curVal, match.Value) == true)
                        {
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }
Пример #9
0
        private static bool MatchCriteria(SubscriptionCriteria criteria, JsonDocument doc)
        {
            if (criteria.BelongsToAnyCollection != null &&
                criteria.BelongsToAnyCollection.Contains(doc.Metadata.Value <string>(Constants.RavenEntityName), StringComparer.InvariantCultureIgnoreCase) == false)
            {
                return(false);
            }

            if (criteria.KeyStartsWith != null && doc.Key.StartsWith(criteria.KeyStartsWith) == false)
            {
                return(false);
            }

            if (criteria.PropertiesMatch != null)
            {
                foreach (var match in criteria.PropertiesMatch)
                {
                    var value = doc.DataAsJson.SelectToken(match.Key);

                    if (value == null)
                    {
                        return(false);
                    }

                    if (RavenJToken.DeepEquals(value, match.Value) == false)
                    {
                        return(false);
                    }
                }
            }

            if (criteria.PropertiesNotMatch != null)
            {
                foreach (var notMatch in criteria.PropertiesNotMatch)
                {
                    var value = doc.DataAsJson.SelectToken(notMatch.Key);

                    if (value != null)
                    {
                        if (RavenJToken.DeepEquals(value, notMatch.Value))
                        {
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }
Пример #10
0
        public async Task BasicSusbscriptionTest()
        {
            using (var store = GetDocumentStore())
            {
                await CreateDocuments(store, 1);

                var lastEtag = store.GetLastWrittenEtag() ?? 0;
                await CreateDocuments(store, 5);

                var subscriptionCriteria = new SubscriptionCriteria
                {
                    Collection = "Things",
                };

                var subsId = await store.AsyncSubscriptions.CreateAsync(subscriptionCriteria, lastEtag);

                using (var subscription = store.AsyncSubscriptions.Open <Thing>(new SubscriptionConnectionOptions
                {
                    SubscriptionId = subsId
                }))
                {
                    var bc = new BlockingCollection <Thing>();

                    subscription.Subscribe(x =>
                    {
                        bc.Add(x);
                    });

                    await subscription.StartAsync();

                    Thing thing;
                    for (var i = 0; i < 5; i++)
                    {
                        Assert.True(bc.TryTake(out thing, 1000));
                    }

                    Assert.False(bc.TryTake(out thing, 50));

                    for (var j = 0; j < 2; j++)
                    {
                        await CreateDocuments(store, 1);

                        Assert.True(bc.TryTake(out thing, 500));
                        Assert.False(bc.TryTake(out thing, 50));
                    }
                }
            }
        }
Пример #11
0
        public Task <long> CreateAsync <T>(SubscriptionCriteria <T> criteria, long startEtag = 0, string database = null)
        {
            if (criteria == null)
            {
                throw new InvalidOperationException("Cannot create a subscription if criteria is null");
            }

            var nonGenericCriteria = new SubscriptionCriteria
            {
                Collection       = documentStore.Conventions.GetTypeTagName(typeof(T)),
                FilterJavaScript = criteria.FilterJavaScript
            };


            return(CreateAsync(nonGenericCriteria, startEtag, database));
        }
        public Task <long> CreateAsync <T>(SubscriptionCriteria <T> criteria, string database = null)
        {
            if (criteria == null)
            {
                throw new InvalidOperationException("Cannot create a subscription if criteria is null");
            }

            var nonGenericCriteria = new SubscriptionCriteria();

            nonGenericCriteria.BelongsToAnyCollection = new [] { documentStore.Conventions.GetTypeTagName(typeof(T)) };
            nonGenericCriteria.KeyStartsWith          = criteria.KeyStartsWith;
            nonGenericCriteria.PropertiesMatch        = criteria.GetPropertiesMatchStrings();
            nonGenericCriteria.PropertiesNotMatch     = criteria.GetPropertiesNotMatchStrings();

            return(CreateAsync(nonGenericCriteria, database));
        }
Пример #13
0
        private IDisposable RegisterForNotificationOnNewDocuments(SubscriptionCriteria criteria)
        {
            _waitForMoreDocuments = new AsyncManualResetEvent(CancellationTokenSource.Token);
            Action <DocumentChangeNotification> registerNotification = notification =>
            {
                if (notification.CollectionName == criteria.Collection)
                {
                    _waitForMoreDocuments.SetByAsyncCompletion();
                }
            };

            TcpConnection.DocumentDatabase.Notifications.OnDocumentChange += registerNotification;
            return(new DisposableAction(() =>
            {
                TcpConnection.DocumentDatabase.Notifications.OnDocumentChange -= registerNotification;
            }));
        }
        public async Task <long> CreateAsync(SubscriptionCriteria criteria, string database = null)
        {
            if (criteria == null)
            {
                throw new InvalidOperationException("Cannot create a subscription if criteria is null");
            }

            var commands = database == null
                                ? documentStore.AsyncDatabaseCommands
                                : documentStore.AsyncDatabaseCommands.ForDatabase(database);

            using (var request = commands.CreateRequest("/subscriptions/create", "POST"))
            {
                await request.WriteAsync(RavenJObject.FromObject(criteria)).ConfigureAwait(false);

                return(request.ReadResponseJson().Value <long>("Id"));
            }
        }
Пример #15
0
        public async Task CreateSubscription()
        {
            using (var store = GetDocumentStore())
            {
                var subscriptionCriteria = new SubscriptionCriteria
                {
                    Collection = "People",
                };
                var subsId = await store.AsyncSubscriptions.CreateAsync(subscriptionCriteria);

                var subscriptionsConfig = await store.AsyncSubscriptions.GetSubscriptionsAsync(0, 10);

                Assert.Equal(1, subscriptionsConfig.Count);
                Assert.Equal(subscriptionCriteria.Collection, subscriptionsConfig[0].Criteria.Collection);
                Assert.Equal(subscriptionCriteria.FilterJavaScript, subscriptionsConfig[0].Criteria.FilterJavaScript);
                Assert.Equal(0, subscriptionsConfig[0].AckEtag);
                Assert.Equal(subsId, subscriptionsConfig[0].SubscriptionId);
            }
        }
Пример #16
0
        public async Task BasicSusbscriptionTest()
        {
            var store = GetDocumentStore();

            await CreateDocuments(store, 1);

            long lastEtag;

            using (var session = store.OpenAsyncSession())
            {
                var thing = await session.LoadAsync <Thing>("things/1");

                lastEtag = session.Advanced.GetEtagFor(thing) ?? 0;
            }
            await CreateDocuments(store, 5);

            var subscriptionCriteria = new SubscriptionCriteria
            {
                Collection = "Things",
            };
            var subsId = await store.AsyncSubscriptions.CreateAsync(subscriptionCriteria, lastEtag);

            using (var subscription = store.AsyncSubscriptions.Open <Thing>(new SubscriptionConnectionOptions()
            {
                SubscriptionId = subsId
            }))
            {
                var list = new BlockingCollection <Thing>();
                subscription.Subscribe(x =>
                {
                    list.Add(x);
                });

                await subscription.StartAsync();

                Thing thing;
                for (var i = 0; i < 5; i++)
                {
                    Assert.True(list.TryTake(out thing, 1000));
                }
                Assert.False(list.TryTake(out thing, 50));
            }
        }
Пример #17
0
        public long CreateSubscription(SubscriptionCriteria criteria)
        {
            long id = -1;

            Database.TransactionalStorage.Batch(accessor =>
            {
                id = accessor.General.GetNextIdentityValue(Constants.RavenSubscriptionsPrefix);

                var config = new SubscriptionConfig
                {
                    SubscriptionId = id,
                    Criteria       = criteria,
                    AckEtag        = Etag.Empty
                };

                SaveSubscriptionConfig(id, config);
            });

            return(id);
        }
Пример #18
0
        public async Task <long> CreateAsync(SubscriptionCriteria criteria, long startEtag = 0, string database = null)
        {
            if (criteria == null)
            {
                throw new InvalidOperationException("Cannot create a subscription if criteria is null");
            }

            JsonOperationContext jsonOperationContext;
            var requestExecuter = documentStore.GetRequestExecuter(database ?? documentStore.DefaultDatabase);

            requestExecuter.ContextPool.AllocateOperationContext(out jsonOperationContext);

            var command = new CreateSubscriptionCommand()
            {
                Context   = jsonOperationContext,
                Criteria  = criteria,
                StartEtag = startEtag
            };
            await requestExecuter.ExecuteAsync(command, jsonOperationContext);

            return(command.Result.Id);
        }
Пример #19
0
 public long Create <T>(SubscriptionCriteria <T> criteria, string database = null)
 {
     return(innerAsync.CreateAsync(criteria, database).ResultUnwrap());
 }
Пример #20
0
        public async Task StronglyTypedDataSubscriptions()
        {
            using (var store = GetDocumentStore())
            {
                using (var session = store.OpenAsyncSession())
                {
                    for (int i = 0; i < 5; i++)
                    {
                        await session.StoreAsync(new PersonWithAddress()
                        {
                            Name    = "James",
                            Address = new Address()
                            {
                                ZipCode = 12345
                            }
                        });

                        await session.StoreAsync(new PersonWithAddress()
                        {
                            Name    = "James",
                            Address = new Address()
                            {
                                ZipCode = 54321
                            }
                        });

                        await session.StoreAsync(new PersonWithAddress()
                        {
                            Name    = "David",
                            Address = new Address()
                            {
                                ZipCode = 12345
                            }
                        });

                        await session.StoreAsync(new Person());
                    }

                    await session.SaveChangesAsync();
                }

                var criteria = new SubscriptionCriteria <PersonWithAddress>
                {
                    FilterJavaScript = "return this.Name == 'James' && this.Address.ZipCode != 54321"
                };


                var id = await store.AsyncSubscriptions.CreateAsync(criteria);

                using (
                    var subscription =
                        store.AsyncSubscriptions.Open <PersonWithAddress>(new SubscriptionConnectionOptions
                {
                    SubscriptionId = id
                }))
                {
                    var users = new BlockingCollection <PersonWithAddress>();

                    subscription.Subscribe(users.Add);
                    await subscription.StartAsync();

                    PersonWithAddress userToTake;
                    for (var i = 0; i < 5; i++)
                    {
                        Assert.True(users.TryTake(out userToTake, 50000));
                        Assert.Equal("James", userToTake.Name);
                        Assert.Equal(12345, userToTake.Address.ZipCode);
                    }

                    Assert.False(users.TryTake(out userToTake, 50));
                }
            }
        }
Пример #21
0
        public void FullBackupToOneZipFile()
        {
            var tempFileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            Directory.CreateDirectory(tempFileName);

            using (var database = CreateDocumentDatabase())
            {
                var context = DocumentsOperationContext.ShortTermSingleUse(database);

                var subscriptionCriteria = new SubscriptionCriteria
                {
                    Collection = "Users",
                };
                var obj          = RavenJObject.FromObject(subscriptionCriteria);
                var objString    = obj.ToString(Formatting.None);
                var stream       = new MemoryStream();
                var streamWriter = new StreamWriter(stream);
                streamWriter.Write(objString);
                streamWriter.Flush();
                stream.Position = 0;
                var reader = context.Read(stream, "docs/1");
                database.SubscriptionStorage.CreateSubscription(reader);

                database.IndexStore.CreateIndex(new IndexDefinition()
                {
                    Name = "Users_ByName",
                    Maps = { "from user in docs.Users select new { user.Name }" },
                    Type = IndexType.Map
                });
                database.IndexStore.CreateIndex(new IndexDefinition()
                {
                    Name = "Users_ByName2",
                    Maps = { "from user in docs.Users select new { user.Name }" },
                    Type = IndexType.Map
                });

                using (var tx = context.OpenWriteTransaction())
                {
                    var doc2 = CreateDocument(context, "users/2", new DynamicJsonValue
                    {
                        ["Name"] = "Edward",
                        [Constants.Metadata.Key] = new DynamicJsonValue
                        {
                            [Constants.Headers.RavenEntityName] = "Users"
                        }
                    });

                    database.DocumentsStorage.Put(context, "users/2", null, doc2);

                    tx.Commit();
                }

                database.SubscriptionStorage.Environment().Options.ManualFlushing = true;
                database.SubscriptionStorage.Environment().FlushLogToDataFile();

                foreach (var index in database.IndexStore.GetIndexes())
                {
                    index._indexStorage.Environment().Options.ManualFlushing = true;
                    index._indexStorage.Environment().FlushLogToDataFile();
                }
                database.DocumentsStorage.Environment.Options.ManualFlushing = true;
                database.DocumentsStorage.Environment.FlushLogToDataFile();

                database.FullBackupTo(Path.Combine(tempFileName, "backup-test.backup"));
                BackupMethods.Full.Restore(Path.Combine(tempFileName, "backup-test.backup"), Path.Combine(tempFileName, "backup-test.data"));
            }
            using (var database = CreateDocumentDatabase(runInMemory: false, dataDirectory: Path.Combine(tempFileName, "backup-test.data")))
            {
                var context = DocumentsOperationContext.ShortTermSingleUse(database);
                using (var tx = context.OpenReadTransaction())
                {
                    Assert.NotNull(database.DocumentsStorage.Get(context, "users/2"));
                    Assert.Equal(database.IndexStore.GetIndex(1).Name, "Users_ByName");
                    Assert.Equal(database.IndexStore.GetIndex(2).Name, "Users_ByName2");
                    Assert.Equal(database.SubscriptionStorage.GetAllSubscriptionsCount(), 1);
                }
            }
        }
Пример #22
0
        public unsafe void GetCriteriaAndEtag(long id, DocumentsOperationContext context, out SubscriptionCriteria criteria, out long startEtag)
        {
            var transactionPersistentContext = new TransactionPersistentContext();

            using (var tx = _environment.ReadTransaction(transactionPersistentContext))
            {
                var config = GetSubscriptionConfig(id, tx);

                int criteriaSize;
                var criteriaPtr       = config.Read(SubscriptionSchema.SubscriptionTable.CriteriaIndex, out criteriaSize);
                var criteriaBlittable = new BlittableJsonReaderObject(criteriaPtr, criteriaSize, context);
                criteria  = JsonDeserializationServer.SubscriptionCriteria(criteriaBlittable);
                startEtag = *(long *)config.Read(SubscriptionSchema.SubscriptionTable.AckEtagIndex, out criteriaSize);
            }
        }
Пример #23
0
        public async Task SubscriptionStrategyConnectIfFree()
        {
            using (var store = GetDocumentStore())
            {
                await CreateDocuments(store, 1);

                long lastEtag;
                using (var session = store.OpenAsyncSession())
                {
                    var thing = await session.LoadAsync <Thing>("things/1");

                    lastEtag = session.Advanced.GetEtagFor(thing) ?? 0;
                }
                await CreateDocuments(store, 5);

                var subscriptionCriteria = new SubscriptionCriteria
                {
                    Collection = "Things",
                };
                var subsId = await store.AsyncSubscriptions.CreateAsync(subscriptionCriteria, lastEtag);

                using (
                    var acceptedSubscription = store.AsyncSubscriptions.Open <Thing>(new SubscriptionConnectionOptions()
                {
                    SubscriptionId = subsId,
                    TimeToWaitBeforeConnectionRetryMilliseconds = 10000
                }))
                {
                    var acceptedSusbscriptionList = new BlockingCollection <Thing>();
                    acceptedSubscription.Subscribe(x =>
                    {
                        acceptedSusbscriptionList.Add(x);
                    });
                    await acceptedSubscription.StartAsync();

                    Thing thing;

                    // wait until we know that connection was established
                    for (var i = 0; i < 5; i++)
                    {
                        Assert.True(acceptedSusbscriptionList.TryTake(out thing, 1000));
                    }
                    Assert.False(acceptedSusbscriptionList.TryTake(out thing, 50));

                    // open second subscription
                    using (
                        var rejectedSusbscription =
                            store.AsyncSubscriptions.Open <Thing>(new SubscriptionConnectionOptions()
                    {
                        SubscriptionId = subsId,
                        Strategy = SubscriptionOpeningStrategy.OpenIfFree,
                        TimeToWaitBeforeConnectionRetryMilliseconds = 6000
                    }))
                    {
                        rejectedSusbscription.Subscribe(thing1 => { });

                        await Assert.ThrowsAsync <SubscriptionInUseException>(async() => await rejectedSusbscription.StartAsync());
                    }
                }
            }
        }
Пример #24
0
        public async Task StronglyTypedDataSubscriptions(string storage)
        {
            using (var store = NewDocumentStore(requestedStorage: storage))
            {
                using (var session = store.OpenSession())
                {
                    for (int i = 0; i < 10; i++)
                    {
                        session.Store(new PersonWithAddress()
                        {
                            Name    = "James",
                            Address = new Address()
                            {
                                ZipCode = 12345
                            }
                        });

                        session.Store(new PersonWithAddress()
                        {
                            Name    = "James",
                            Address = new Address()
                            {
                                ZipCode = 54321
                            }
                        });

                        session.Store(new PersonWithAddress()
                        {
                            Name    = "David",
                            Address = new Address()
                            {
                                ZipCode = 12345
                            }
                        });

                        session.Store(new Person());
                    }

                    session.SaveChanges();
                }

                var criteria = new SubscriptionCriteria <PersonWithAddress>();
                criteria.PropertyMatch(x => x.Name, "James");
                criteria.PropertyNotMatch(x => x.Address.ZipCode, 54321);

                var id = await store.AsyncSubscriptions.CreateAsync(criteria);

                var subscription = await store.AsyncSubscriptions.OpenAsync <PersonWithAddress>(id, new SubscriptionConnectionOptions());

                var users = new List <PersonWithAddress>();

                subscription.Subscribe(users.Add);

                Assert.True(SpinWait.SpinUntil(() => users.Count >= 10, TimeSpan.FromSeconds(60)));

                Assert.Equal(10, users.Count);

                foreach (var user in users)
                {
                    Assert.Equal("James", user.Name);
                    Assert.Equal(12345, user.Address.ZipCode);
                }
            }
        }
Пример #25
0
 public long Create(SubscriptionCriteria criteria, long startEtag = 0, string database = null)
 {
     return(AsyncHelpers.RunSync(() => innerAsync.CreateAsync(criteria, startEtag, database)));
 }
Пример #26
0
        public async Task SubscriptionStrategyConnectIfFree()
        {
            using (var store = GetDocumentStore())
            {
                await CreateDocuments(store, 1);

                var lastEtag = store.GetLastWrittenEtag() ?? 0;
                await CreateDocuments(store, 5);

                var subscriptionCriteria = new SubscriptionCriteria
                {
                    Collection = "Things",
                };
                var subsId = await store.AsyncSubscriptions.CreateAsync(subscriptionCriteria, lastEtag);

                using (
                    var acceptedSubscription = store.AsyncSubscriptions.Open <Thing>(new SubscriptionConnectionOptions()
                {
                    SubscriptionId = subsId,
                    TimeToWaitBeforeConnectionRetryMilliseconds = 20000
                }))
                {
                    var acceptedSusbscriptionList = new BlockingCollection <Thing>();
                    acceptedSubscription.Subscribe(x =>
                    {
                        acceptedSusbscriptionList.Add(x);
                    });
                    await acceptedSubscription.StartAsync();

                    Thing thing;

                    // wait until we know that connection was established
                    for (var i = 0; i < 5; i++)
                    {
                        Assert.True(acceptedSusbscriptionList.TryTake(out thing, 1000));
                    }

                    Assert.False(acceptedSusbscriptionList.TryTake(out thing, 50));

                    // open second subscription
                    using (
                        var rejectedSusbscription =
                            store.AsyncSubscriptions.Open <Thing>(new SubscriptionConnectionOptions()
                    {
                        SubscriptionId = subsId,
                        Strategy = SubscriptionOpeningStrategy.OpenIfFree,
                        TimeToWaitBeforeConnectionRetryMilliseconds = 2000
                    }))
                    {
                        rejectedSusbscription.Subscribe(thing1 => { });

                        // sometime not throwing (on linux) when written like this:
                        // await Assert.ThrowsAsync<SubscriptionInUseException>(async () => await rejectedSusbscription.StartAsync());
                        // so we put this in a try block
                        try
                        {
                            await rejectedSusbscription.StartAsync();

                            Assert.False(true); // we didn't throw - so test failed
                        }
                        catch (SubscriptionInUseException)
                        {
                        }
                    }
                }
            }
        }
Пример #27
0
        public async Task SubscriptionSimpleTakeOverStrategy()
        {
            using (var store = GetDocumentStore())
            {
                await CreateDocuments(store, 1);

                var lastEtag = store.GetLastWrittenEtag() ?? 0;
                await CreateDocuments(store, 5);

                var subscriptionCriteria = new SubscriptionCriteria
                {
                    Collection = "Things",
                };
                var subsId = await store.AsyncSubscriptions.CreateAsync(subscriptionCriteria, lastEtag);

                using (
                    var acceptedSubscription = store.AsyncSubscriptions.Open <Thing>(new SubscriptionConnectionOptions()
                {
                    SubscriptionId = subsId
                }))
                {
                    var acceptedSusbscriptionList  = new BlockingCollection <Thing>();
                    var takingOverSubscriptionList = new BlockingCollection <Thing>();

                    acceptedSubscription.Subscribe(x =>
                    {
                        acceptedSusbscriptionList.Add(x);
                    });

                    var batchProccessedByFirstSubscription = new AsyncManualResetEvent();

                    acceptedSubscription.AfterAcknowledgment +=
                        () => batchProccessedByFirstSubscription.SetByAsyncCompletion();

                    await acceptedSubscription.StartAsync();

                    Thing thing;

                    // wait until we know that connection was established
                    for (var i = 0; i < 5; i++)
                    {
                        Assert.True(acceptedSusbscriptionList.TryTake(out thing, 5000), "no doc");
                    }

                    Assert.True(await batchProccessedByFirstSubscription.WaitAsync(TimeSpan.FromSeconds(15)), "no ack");

                    Assert.False(acceptedSusbscriptionList.TryTake(out thing));

                    // open second subscription
                    using (var takingOverSubscription = store.AsyncSubscriptions.Open <Thing>(new SubscriptionConnectionOptions()
                    {
                        SubscriptionId = subsId,
                        Strategy = SubscriptionOpeningStrategy.TakeOver
                    }))
                    {
                        takingOverSubscription.Subscribe(x => takingOverSubscriptionList.Add(x));
                        await takingOverSubscription.StartAsync();

                        await CreateDocuments(store, 5);

                        // wait until we know that connection was established
                        for (var i = 0; i < 5; i++)
                        {
                            Assert.True(takingOverSubscriptionList.TryTake(out thing, 5000), "no doc takeover");
                        }
                        Assert.False(takingOverSubscriptionList.TryTake(out thing));
                    }
                }
            }
        }
Пример #28
0
        public async Task SubscriptionWaitStrategy()
        {
            using (var store = GetDocumentStore())
            {
                await CreateDocuments(store, 1);

                var lastEtag = store.GetLastWrittenEtag() ?? 0;
                await CreateDocuments(store, 5);

                var subscriptionCriteria = new SubscriptionCriteria
                {
                    Collection = "Things",
                };
                var subsId = await store.AsyncSubscriptions.CreateAsync(subscriptionCriteria, lastEtag);

                using (
                    var acceptedSubscription = store.AsyncSubscriptions.Open <Thing>(new SubscriptionConnectionOptions()
                {
                    SubscriptionId = subsId
                }))
                {
                    var acceptedSusbscriptionList = new BlockingCollection <Thing>();
                    var waitingSubscriptionList   = new BlockingCollection <Thing>();

                    var ackSentAmre = new AsyncManualResetEvent();
                    acceptedSubscription.AfterAcknowledgment += () => ackSentAmre.SetByAsyncCompletion();

                    acceptedSubscription.Subscribe(x =>
                    {
                        acceptedSusbscriptionList.Add(x);
                        Thread.Sleep(20);
                    });

                    await acceptedSubscription.StartAsync();

                    // wait until we know that connection was established

                    Thing thing;
                    // wait until we know that connection was established
                    for (var i = 0; i < 5; i++)
                    {
                        Assert.True(acceptedSusbscriptionList.TryTake(out thing, 50000));
                    }

                    Assert.False(acceptedSusbscriptionList.TryTake(out thing, 50));

                    // open second subscription
                    using (
                        var waitingSubscription =
                            store.AsyncSubscriptions.Open <Thing>(new SubscriptionConnectionOptions()
                    {
                        SubscriptionId = subsId,
                        Strategy = SubscriptionOpeningStrategy.WaitForFree,
                        TimeToWaitBeforeConnectionRetryMilliseconds = 250
                    }))
                    {
                        waitingSubscription.Subscribe(x =>
                        {
                            waitingSubscriptionList.Add(x);
                        });
                        var taskStarted = waitingSubscription.StartAsync();
                        var completed   = await Task.WhenAny(taskStarted, Task.Delay(60000));


                        Assert.False(completed == taskStarted);

                        Assert.True(await ackSentAmre.WaitAsync(TimeSpan.FromSeconds(50)));

                        acceptedSubscription.Dispose();

                        await CreateDocuments(store, 5);

                        // wait until we know that connection was established
                        for (var i = 0; i < 5; i++)
                        {
                            Assert.True(waitingSubscriptionList.TryTake(out thing, 1000));
                        }

                        Assert.False(waitingSubscriptionList.TryTake(out thing, 50));
                    }
                }
            }
        }
Пример #29
0
 public long Create <T>(SubscriptionCriteria <T> criteria, string database = null)
 {
     return(AsyncHelpers.RunSync(() => innerAsync.CreateAsync(criteria, database)));
 }