예제 #1
0
        public void Never_ever()
        {
            var db = Guid.NewGuid().ToString();

            using (var documentStore = new DocumentStore
            {
                Url = "http://localhost:8081",
                DefaultDatabase = db,
            }.Initialize())
            {
                new TimeoutsIndex().Execute(documentStore);

                var persister = new TimeoutPersister
                {
                    DocumentStore       = documentStore,
                    EndpointName        = "foo",
                    TriggerCleanupEvery = TimeSpan.FromHours(1),             // Make sure cleanup doesn't run automatically
                };

                var startSlice = DateTime.UtcNow.AddYears(-10);
                // avoid cleanup from running during the test by making it register as being run
                Assert.AreEqual(0, persister.GetCleanupChunk(startSlice).Count());

                var expected       = new List <Tuple <string, DateTime> >();
                var lastTimeout    = DateTime.UtcNow;
                var finishedAdding = false;

                new Thread(() =>
                {
                    var sagaId = Guid.NewGuid();
                    for (var i = 0; i < 10000; i++)
                    {
                        var td = new TimeoutData
                        {
                            SagaId               = sagaId,
                            Destination          = new Address("queue", "machine"),
                            Time                 = DateTime.UtcNow.AddSeconds(RandomProvider.GetThreadRandom().Next(1, 20)),
                            OwningTimeoutManager = string.Empty,
                        };
                        persister.Add(td);
                        expected.Add(new Tuple <string, DateTime>(td.Id, td.Time));
                        lastTimeout = (td.Time > lastTimeout) ? td.Time : lastTimeout;
                    }
                    finishedAdding = true;
                    Trace.WriteLine("*** Finished adding ***");
                }).Start();

                // Mimic the behavior of the TimeoutPersister coordinator
                var         found = 0;
                TimeoutData tmptd;
                while (!finishedAdding || startSlice < lastTimeout)
                {
                    DateTime nextRetrieval;
                    var      timeoutDatas = persister.GetNextChunk(startSlice, out nextRetrieval);
                    foreach (var timeoutData in timeoutDatas)
                    {
                        if (startSlice < timeoutData.Item2)
                        {
                            startSlice = timeoutData.Item2;
                        }

                        Assert.IsTrue(persister.TryRemove(timeoutData.Item1, out tmptd));
                        found++;
                    }
                }

                WaitForIndexing(documentStore);

                // If the persister reports stale results have been seen at one point during its normal operation,
                // we need to perform manual cleaup.
                while (true)
                {
                    var chunkToCleanup = persister.GetCleanupChunk(DateTime.UtcNow.AddDays(1)).ToArray();
                    if (chunkToCleanup.Length == 0)
                    {
                        break;
                    }

                    found += chunkToCleanup.Length;
                    foreach (var tuple in chunkToCleanup)
                    {
                        Assert.IsTrue(persister.TryRemove(tuple.Item1, out tmptd));
                    }

                    WaitForIndexing(documentStore);
                }

                using (var session = documentStore.OpenSession())
                {
                    var results = session.Query <TimeoutData>().ToList();
                    Assert.AreEqual(0, results.Count);
                }

                Assert.AreEqual(expected.Count, found);
            }
        }