예제 #1
0
        public void First_modification_date_is_returned_on_dequeue()
        {
            expirationResult = new Result <NotificationUpdateRecord>(TimeSpan.FromSeconds(10));
            var now   = DateTime.UtcNow;
            var queue = new NotificationDelayQueue(TimeSpan.FromMilliseconds(500), ExpirationCallback);

            queue.Enqueue("foo", 1, 1, now);
            queue.Enqueue("foo", 1, 1, now.AddMinutes(1));
            queue.Enqueue("foo", 1, 1, now.AddMinutes(2));
            expirationResult.Wait();
            var pages = expirationResult.Value.Pages.ToList();

            Assert.AreEqual(1, pages.Count);
            Assert.AreEqual(now, pages[0].Item2);
        }
        //--- Methods ---
        protected override Yield Start(XDoc config, IContainer container, Result result)
        {
            yield return(Coroutine.Invoke(base.Start, config, new Result()));

            // set up plug for phpscript that will handle the notifications
            _emailer = Plug.New(config["uri.emailer"].AsUri);

            // set up plug deki, so we can validate users
            _deki = Plug.New(config["uri.deki"].AsUri);

            // get the apikey, which we will need as a subscription auth token for subscriptions not done on behalf of a user
            _apikey = config["apikey"].AsText;
            _cache  = new PageChangeCache(_deki.With("apikey", _apikey), TimeSpan.FromSeconds(config["page-cache-ttl"].AsInt ?? 2));

            if (!container.IsRegistered <IPageSubscriptionInstance>())
            {
                var builder = new ContainerBuilder();
                builder.Register <PageSubscriptionInstance>().As <IPageSubscriptionInstance>().FactoryScoped();
                builder.Build(container);
            }

            // TODO (arnec): this should be hitting the API to retrieve resources

            // resource manager for email template
            var resourcePath = Config["resources-path"].AsText;

            if (!string.IsNullOrEmpty(resourcePath))
            {
                _resourceManager = new PlainTextResourceManager(Environment.ExpandEnvironmentVariables(resourcePath));
            }
            else
            {
                // creating a test resource manager
                _log.WarnFormat("'resource-path' was not defined in Config, using a test resource manager for email templating");
                var testSet = new TestResourceSet {
                    { "Notification.Page.email-subject", "Page Modified" },
                    { "Notification.Page.email-header", "The following pages have changed:" }
                };
                _resourceManager = new PlainTextResourceManager(testSet);
            }

            // set up subscription for pubsub
            var subscriptionSet = new XDoc("subscription-set")
                                  .Elem("uri.owner", Self.Uri.AsServerUri().ToString())
                                  .Start("subscription")
                                  .Elem("channel", "event://*/deki/users/*")
                                  .Add(DreamCookie.NewSetCookie("service-key", InternalAccessKey, Self.Uri).AsSetCookieDocument)
                                  .Start("recipient")
                                  .Attr("authtoken", _apikey)
                                  .Elem("uri", Self.Uri.AsServerUri().At("updateuser").ToString())
                                  .End()
                                  .End()
                                  .Start("subscription")
                                  .Elem("channel", "event://*/deki/pages/create")
                                  .Elem("channel", "event://*/deki/pages/update")
                                  .Elem("channel", "event://*/deki/pages/delete")
                                  .Elem("channel", "event://*/deki/pages/revert")
                                  .Elem("channel", "event://*/deki/pages/move")
                                  .Elem("channel", "event://*/deki/pages/tags/update")
                                  .Elem("channel", "event://*/deki/pages/dependentschanged/comments/create")
                                  .Elem("channel", "event://*/deki/pages/dependentschanged/comments/update")
                                  .Elem("channel", "event://*/deki/pages/dependentschanged/comments/delete")
                                  .Elem("channel", "event://*/deki/pages/dependentschanged/files/create")
                                  .Elem("channel", "event://*/deki/pages/dependentschanged/files/update")
                                  .Elem("channel", "event://*/deki/pages/dependentschanged/files/delete")
                                  .Elem("channel", "event://*/deki/pages/dependentschanged/files/properties/*")
                                  .Elem("channel", "event://*/deki/pages/dependentschanged/files/restore")
                                  .Add(DreamCookie.NewSetCookie("service-key", InternalAccessKey, Self.Uri).AsSetCookieDocument)
                                  .Start("recipient")
                                  .Attr("authtoken", _apikey)
                                  .Elem("uri", Self.Uri.AsServerUri().At("notify").ToString())
                                  .End()
                                  .End();
            Result <DreamMessage> subscribe;

            yield return(subscribe = PubSub.At("subscribers").PostAsync(subscriptionSet));

            string accessKey = subscribe.Value.ToDocument()["access-key"].AsText;
            XUri   location  = subscribe.Value.Headers.Location;

            Cookies.Update(DreamCookie.NewSetCookie("access-key", accessKey, location), null);
            _subscriptionLocation = Plug.New(location.AsLocalUri().WithoutQuery());
            _log.DebugFormat("set up initial subscription location at {0}", _subscriptionLocation.Uri);

            // set up notification accumulator queue
            TimeSpan accumulationMinutes = TimeSpan.FromSeconds(config["accumulation-time"].AsInt ?? 10 * 60);

            _log.DebugFormat("Initializing queue with {0:0.00} minute accumulation", accumulationMinutes.TotalMinutes);
            _notificationQueue = new NotificationDelayQueue(accumulationMinutes, SendEmail);
            result.Return();
        }