//--- Methods --- protected override Yield Start(XDoc config, Result result) { yield return(Coroutine.Invoke(base.Start, config, new Result())); _varnish = Plug.New(Config["uri.varnish"].AsUri); _deki = Plug.New(Config["uri.deki"].AsUri); _apikey = Config["apikey"].AsText; _delayPurgeTimespan = TimeSpan.FromSeconds(config["varnish-purge-delay"].AsInt ?? 10); var dispatcher = new UpdateRecordDispatcher(OnQueueExpire); _updateDelayQueue = new UpdateDelayQueue(_delayPurgeTimespan, dispatcher); // set up subscription for pubsub XDoc subscriptionSet = new XDoc("subscription-set") .Elem("uri.owner", Self.Uri) .Start("subscription") .Add(DreamCookie.NewSetCookie("service-key", InternalAccessKey, Self.Uri).AsSetCookieDocument) .Elem("channel", "event://*/deki/pages/create") .Elem("channel", "event://*/deki/pages/move") .Elem("channel", "event://*/deki/pages/update") .Elem("channel", "event://*/deki/pages/delete") .Elem("channel", "event://*/deki/pages/revert") .Elem("channel", "event://*/deki/pages/createalias") .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/move") .Elem("channel", "event://*/deki/pages/dependentschanged/files/restore") .Elem("channel", "event://*/deki/files/create") .Elem("channel", "event://*/deki/files/update") .Elem("channel", "event://*/deki/files/delete") .Elem("channel", "event://*/deki/files/move") .Elem("channel", "event://*/deki/files/restore") .Start("recipient") .Attr("authtoken", _apikey) .Elem("uri", Self.Uri.At("queue")) .End() .End(); Result <DreamMessage> subscriptionResult; yield return(subscriptionResult = PubSub.At("subscribers").PostAsync(subscriptionSet)); string accessKey = subscriptionResult.Value.ToDocument()["access-key"].AsText; XUri location = subscriptionResult.Value.Headers.Location; Cookies.Update(DreamCookie.NewSetCookie("access-key", accessKey, location), null); _subscriptionLocation = location.AsLocalUri().WithoutQuery(); _log.DebugFormat("subscribed VarnishPurgeService for events at {0}", _subscriptionLocation); result.Return(); }
public void Failed_tasks_sleeps_and_retries() { var handler = new DispatchHandler(); var dispatcher = new UpdateRecordDispatcher(handler.Dispatch, 1, 1, 2.Seconds()); var firstAttempt = handler.AddCallback((d, r) => r.Throw(new Exception()), new Result <UpdateRecord>(5.Seconds())); var secondAttempt = handler.AddCallback((d, r) => { }, new Result <UpdateRecord>(5.Seconds())); dispatcher.Dispatch(new UpdateRecord(new XUri("mock://foo"), new XDoc("meta"), "default"), new Result()); Assert.IsFalse(firstAttempt.Block().HasException, "first attempt wasn't called"); var stopwatch = Stopwatch.StartNew(); Assert.IsFalse(secondAttempt.Block().HasException, "second attempt wasn't called"); stopwatch.Stop(); Assert.GreaterOrEqual(stopwatch.Elapsed, 2.Seconds(), string.Format("expected at least 2 second delay, took {0:0.00}s", stopwatch.Elapsed.TotalSeconds)); }
public void Dispatcher_retries_specified_times() { var handler = new DispatchHandler(); var dispatcher = new UpdateRecordDispatcher(handler.Dispatch, 1, 2, 0.Seconds()); var firstAttempt = handler.AddCallback((d, r) => r.Throw(new Exception()), new Result <UpdateRecord>(2.Seconds())); var secondAttempt = handler.AddCallback((d, r) => r.Throw(new Exception()), new Result <UpdateRecord>(2.Seconds())); var thirddAttempt = handler.AddCallback((d, r) => r.Throw(new Exception()), new Result <UpdateRecord>(2.Seconds())); var fourthAttempt = handler.AddCallback((d, r) => r.Throw(new Exception()), new Result <UpdateRecord>(5.Seconds())); dispatcher.Dispatch(new UpdateRecord(new XUri("mock://foo"), new XDoc("meta"), "default"), new Result()); Assert.IsFalse(firstAttempt.Block().HasException, "first attempt wasn't called"); Assert.IsFalse(secondAttempt.Block().HasException, "second attempt wasn't called"); Assert.IsFalse(thirddAttempt.Block().HasException, "third attempt wasn't called"); Assert.IsTrue(fourthAttempt.Block().HasException, "fourth attempt shouldn't have happened"); }
public void Failed_task_sleep_does_not_block_next_task() { var handler = new DispatchHandler(); var dispatcher = new UpdateRecordDispatcher(handler.Dispatch, 1, 1, 2.Seconds()); var r1 = new UpdateRecord(new XUri("mock://foo"), new XDoc("meta"), "default"); var r2 = new UpdateRecord(new XUri("mock://foo"), new XDoc("meta"), "default"); var r1firstAttempt = handler.AddCallback((d, r) => r.Throw(new Exception()), new Result <UpdateRecord>(1.Seconds())); var r2firstAttempt = handler.AddCallback((d, r) => { }, new Result <UpdateRecord>(1.Seconds())); var r1SecondAttempt = handler.AddCallback((d, r) => { }, new Result <UpdateRecord>(5.Seconds())); dispatcher.Dispatch(r1, new Result()); dispatcher.Dispatch(r2, new Result()); Assert.IsFalse(r1firstAttempt.Block().HasException, "r1 first attempt wasn't called"); Assert.IsFalse(r1firstAttempt.Block().HasException, "r2 first attempt wasn't called"); Assert.IsFalse(r1SecondAttempt.Block().HasException, "r2 second attempt wasn't called"); }