Esempio n. 1
0
        public async Task CreationExamples()
        {
            string         name;
            IDocumentStore store = new DocumentStore();

            #region create_whole_collection_generic_with_name

            name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions <Order>
            {
                Name = "OrdersProcessingSumbscription"
            });

            #endregion


            #region create_whole_collection_generic_with_mentor_node

            name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions <Order>
            {
                MentorNode = "D"
            });

            #endregion


            #region create_whole_collection_generic1

            name = await store.Subscriptions.CreateAsync <Order>();

            #endregion

            #region create_whole_collection_RQL

            name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions()
            {
                Query = "From Orders"
            });

            #endregion

            #region create_filter_only_generic

            name = await store.Subscriptions.CreateAsync <Order>(x =>
                                                                 x.Lines.Sum(line => line.PricePerUnit *line.Quantity) > 100);

            #endregion

            #region create_filter_only_RQL

            name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions()
            {
                Query = @"
                            declare function getOrderLinesSum(doc){
                                var sum = 0;
                                for (var i in doc.Lines) { sum += doc.Lines[i];}
                                return sum;
                            }
                            From Orders as o 
                            Where getOrderLinesSum(o) > 100"
            });

            #endregion

            #region create_filter_and_projection_generic

            name = store.Subscriptions.Create(
                new SubscriptionCreationOptions <Order>()
            {
                Filter     = x => x.Lines.Sum(line => line.PricePerUnit * line.Quantity) > 100,
                Projection = x => new
                {
                    Id    = x.Id,
                    Total = x.Lines.Sum(line => line.PricePerUnit * line.Quantity)
                }
            });

            #endregion

            #region create_filter_and_projection_RQL

            name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions()
            {
                Query = @"declare function getOrderLinesSum(doc){
                                var sum = 0;
                                for (var i in doc.Lines) { sum += doc.Lines[i];}
                                return sum;
                            }

                            declare function projectOrder(doc){
                                return {
                                    Id: order.Id,
                                    Total: getOrderLinesSum(order)
                                };
                            }

                            From Orders as o 
                            Where getOrderLinesSum(o) > 100
                            Select projectOrder(o)"
            });

            #endregion

            #region create_filter_and_load_document_generic

            name = store.Subscriptions.Create(
                new SubscriptionCreationOptions <Order>()
            {
                Filter     = x => x.Lines.Sum(line => line.PricePerUnit * line.Quantity) > 100,
                Projection = x => new
                {
                    Id           = x.Id,
                    Total        = x.Lines.Sum(line => line.PricePerUnit * line.Quantity),
                    ShipTo       = x.ShipTo,
                    EmployeeName = RavenQuery.Load <Employee>(x.Employee).FirstName + " " +
                                   RavenQuery.Load <Employee>(x.Employee).LastName
                }
            });

            #endregion

            #region create_filter_and_load_document_RQL

            name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions()
            {
                Query = @"declare function getOrderLinesSum(doc){
                                var sum = 0;
                                for (var i in doc.Lines) { sum += doc.Lines[i];}
                                return sum;
                            }

                            declare function projectOrder(doc){
                                var employee = load(doc.Employee);
                                return {
                                    Id: order.Id,
                                    Total: getOrderLinesSum(order),
                                    ShipTo: order.ShipTo,
                                    EmployeeName: employee.FirstName + ' ' + employee.LastName

                                };
                            }

                            From Orders as o 
                            Where getOrderLinesSum(o) > 100
                            Select projectOrder(o)"
            });

            #endregion


            #region create_simple_revisions_subscription_generic

            name = store.Subscriptions.Create(
                new SubscriptionCreationOptions <Revision <Order> >());

            #endregion

            #region create_simple_revisions_subscription_RQL

            name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions()
            {
                Query = @"From Orders (Revisions = true)"
            });

            #endregion



            #region use_simple_revision_subscription_generic

            SubscriptionWorker <Revision <Order> > revisionWorker = store.Subscriptions.GetSubscriptionWorker <Revision <Order> >(name);

            await revisionWorker.Run((SubscriptionBatch <Revision <Order> > x) =>
            {
                foreach (var documentsPair in x.Items)
                {
                    var prev    = documentsPair.Result.Previous;
                    var current = documentsPair.Result.Current;

                    ProcessOrderChanges(prev, current);
                }
            }
                                     );

            #endregion

            void ProcessOrderChanges(Order prev, Order cur)
            {
            }

            #region create_projected_revisions_subscription_generic

            name = store.Subscriptions.Create(
                new SubscriptionCreationOptions <Revision <Order> >()
            {
                Filter     = tuple => tuple.Current.Lines.Count > tuple.Previous.Lines.Count,
                Projection = tuple => new
                {
                    PreviousRevenue = tuple.Previous.Lines.Sum(x => x.PricePerUnit * x.Quantity),
                    CurrentRevenue  = tuple.Current.Lines.Sum(x => x.PricePerUnit * x.Quantity)
                }
            });

            #endregion

            #region create_projected_revisions_subscription_RQL

            name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions()
            {
                Query = @"declare function getOrderLinesSum(doc){
                                var sum = 0;
                                for (var i in doc.Lines) { sum += doc.Lines[i];}
                                return sum;
                            }

                        From Orders (Revisions = true)
                        Where getOrderLinesSum(this.Current)  > getOrderLinesSum(this.Previous)
                        Select 
                        {
                            PreviousRevenue: getOrderLinesSum(this.Previous),
                            CurrentRevenue: getOrderLinesSum(this.Current)                            
                        }"
            });

            #endregion

            #region consume_revisions_subscription_generic

            SubscriptionWorker <OrderRevenues> revenuesComparisonWorker = store.Subscriptions.GetSubscriptionWorker <OrderRevenues>(name);

            await revenuesComparisonWorker.Run(x =>
            {
                foreach (var item in x.Items)
                {
                    Console.WriteLine($"Revenue for order with Id: {item.Id} grown from {item.Result.PreviousRevenue} to {item.Result.CurrentRevenue}");
                }
            });

            #endregion

            SubscriptionWorker <Order> subscription;
            var cancellationToken = new CancellationTokenSource().Token;
            #region consumption_0
            var subscriptionName = await store.Subscriptions.CreateAsync <Order>(x => x.Company == "companies/11");

            subscription = store.Subscriptions.GetSubscriptionWorker <Order>(subscriptionName);
            var subscriptionTask = subscription.Run(x =>
                                                    x.Items.ForEach(item =>
                                                                    Console.WriteLine($"Order #{item.Result.Id} will be shipped via: {item.Result.ShipVia}")),
                                                    cancellationToken);

            await subscriptionTask;
            #endregion
            #region open_1
            subscription = store.Subscriptions.GetSubscriptionWorker <Order>(name);
            #endregion

            #region open_2
            subscription = store.Subscriptions.GetSubscriptionWorker <Order>(new SubscriptionWorkerOptions(name)
            {
                Strategy = SubscriptionOpeningStrategy.WaitForFree
            });
            #endregion

            #region open_3
            subscription = store.Subscriptions.GetSubscriptionWorker <Order>(new SubscriptionWorkerOptions(name)
            {
                Strategy               = SubscriptionOpeningStrategy.WaitForFree,
                MaxDocsPerBatch        = 500,
                IgnoreSubscriberErrors = true
            });
            #endregion

            #region create_subscription_with_includes_strongly_typed
            store.Subscriptions.Create(new SubscriptionCreationOptions <Order>()
            {
                Includes = builder => builder
                           .IncludeDocuments(x => x.Lines.Select(y => y.Product))
            });
            #endregion
            #region create_subscription_with_includes_rql_path
            store.Subscriptions.Create(new SubscriptionCreationOptions()
            {
                Query = @"from Orders include Lines[].Product"
            });
            #endregion

            #region create_subscription_with_includes_rql_javascript
            store.Subscriptions.Create(new SubscriptionCreationOptions()
            {
                Query = @"
                            declare function includeProducts(doc) 
                            {
                                doc.IncludedFields=0;
                                doc.LinesCount = doc.Lines.length;
                                for (let i=0; i< doc.Lines.length; i++)
                                {
                                    doc.IncludedFields++;
                                    include(doc.Lines[i].Product);
                                }
                                return doc;
                            }
                            from Orders as o select includeProducts(o)"
            });
            #endregion
        }
Esempio n. 2
0
        public async Task DistributedRevisionsSubscription(int nodesAmount)
        {
            var uniqueRevisions = new HashSet <string>();
            var uniqueDocs      = new HashSet <string>();

            var(_, leader) = await CreateRaftCluster(nodesAmount).ConfigureAwait(false);

            var defaultDatabase = GetDatabaseName();

            await CreateDatabaseInCluster(defaultDatabase, nodesAmount, leader.WebUrl).ConfigureAwait(false);

            using (var store = new DocumentStore
            {
                Urls = new[] { leader.WebUrl },
                Database = defaultDatabase
            }.Initialize())
            {
                await SetupRevisions(leader, defaultDatabase).ConfigureAwait(false);

                var reachedMaxDocCountMre = new AsyncManualResetEvent();
                var ackSent = new AsyncManualResetEvent();

                var continueMre = new AsyncManualResetEvent();

                await GenerateDistributedRevisionsDataAsync(defaultDatabase);

                var subscriptionId = await store.Subscriptions.CreateAsync <Revision <User> >().ConfigureAwait(false);

                var docsCount              = 0;
                var revisionsCount         = 0;
                var expectedRevisionsCount = 0;
                SubscriptionWorker <Revision <User> > subscription = null;
                int i;
                for (i = 0; i < 10; i++)
                {
                    subscription = store.Subscriptions.GetSubscriptionWorker <Revision <User> >(new SubscriptionWorkerOptions(subscriptionId)
                    {
                        MaxErroneousPeriod = nodesAmount == 5 ? TimeSpan.FromSeconds(15) : TimeSpan.FromSeconds(5),
                        MaxDocsPerBatch    = 1,
                        TimeToWaitBeforeConnectionRetry = TimeSpan.FromMilliseconds(100)
                    });

                    subscription.AfterAcknowledgment += async b =>
                    {
                        Assert.True(await continueMre.WaitAsync(TimeSpan.FromSeconds(60)));

                        try
                        {
                            if (revisionsCount == expectedRevisionsCount)
                            {
                                continueMre.Reset();
                                ackSent.Set();
                            }

                            Assert.True(await continueMre.WaitAsync(TimeSpan.FromSeconds(60)));
                        }
                        catch (Exception)
                        {
                        }
                    };
                    var started = new AsyncManualResetEvent();

                    var task = subscription.Run(b =>
                    {
                        started.Set();
                        HandleSubscriptionBatch(nodesAmount, b, uniqueDocs, ref docsCount, uniqueRevisions, reachedMaxDocCountMre, ref revisionsCount);
                    });
                    var cont = task.ContinueWith(t =>
                    {
                        reachedMaxDocCountMre.SetException(t.Exception);
                        ackSent.SetException(t.Exception);
                    }, TaskContinuationOptions.OnlyOnFaulted);

                    await Task.WhenAny(task, started.WaitAsync(TimeSpan.FromSeconds(60)));

                    if (started.IsSet)
                    {
                        break;
                    }

                    Assert.IsType <SubscriptionDoesNotExistException>(task.Exception.InnerException);

                    subscription.Dispose();
                }

                Assert.NotEqual(i, 10);

                expectedRevisionsCount = nodesAmount + 2;
                continueMre.Set();

                Assert.True(await ackSent.WaitAsync(_reasonableWaitTime).ConfigureAwait(false), $"Doc count is {docsCount} with revisions {revisionsCount}/{expectedRevisionsCount} (1st assert)");
                ackSent.Reset(true);

                var disposedTag = await KillServerWhereSubscriptionWorks(defaultDatabase, subscription.SubscriptionName).ConfigureAwait(false);
                await WaitForResponsibleNodeToChange(defaultDatabase, subscription.SubscriptionName, disposedTag);

                continueMre.Set();
                expectedRevisionsCount += 2;

                Assert.True(await ackSent.WaitAsync(_reasonableWaitTime).ConfigureAwait(false), $"Doc count is {docsCount} with revisions {revisionsCount}/{expectedRevisionsCount} (2nd assert)");
                ackSent.Reset(true);
                continueMre.Set();

                expectedRevisionsCount = (int)Math.Pow(nodesAmount, 2);
                if (nodesAmount == 5)
                {
                    var secondDisposedTag = await KillServerWhereSubscriptionWorks(defaultDatabase, subscription.SubscriptionName).ConfigureAwait(false);
                    await WaitForResponsibleNodeToChange(defaultDatabase, subscription.SubscriptionName, secondDisposedTag);
                }

                Assert.True(await reachedMaxDocCountMre.WaitAsync(_reasonableWaitTime).ConfigureAwait(false), $"Doc count is {docsCount} with revisions {revisionsCount}/{expectedRevisionsCount} (3rd assert)");
            }
        }