//--- Constructors --- internal InMemoryKeyValueCache(ISerializer serializer, int maxSize, TaskTimerFactory timerFactory) { _serializer = serializer; _maxSize = maxSize; _flushTimer = timerFactory.New(TimeSpan.FromSeconds(1), Flush, null, TaskEnv.None); _cache = new ExpiringDictionary <string, Entry>(timerFactory); }
public void Can_access_dictionary_during_expiration_event() { var expired = new ManualResetEvent(false); var changed = new ManualResetEvent(false); var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(1); ExpiringDictionary <int, string> .Entry entry = null; var set = new ExpiringDictionary <int, string>(TaskTimerFactory.Current); set.EntryExpired += (s, e) => { entry = e.Entry; set.Delete(e.Entry.Key); expired.Set(); }; set.CollectionChanged += (s, e) => changed.Set(); set.Set(k, v, ttl); Assert.IsTrue(changed.WaitOne(5000)); Assert.IsTrue(expired.WaitOne(5000)); Assert.AreEqual(k, entry.Key); Assert.AreEqual(v, entry.Value); Assert.AreEqual(ttl.WithoutMilliseconds(), entry.TTL.WithoutMilliseconds()); Assert.IsNull(set[k]); }
//--- Methods --- protected override IEnumerator <IYield> Start(XDoc config, Result result) { yield return(Coroutine.Invoke(base.Start, config, new Result())); _processingQueue = new ProcessingQueue <XDoc>(CallUpdate); _instances = new ExpiringDictionary <string, PackageUpdater>(TimerFactory, true); _apikey = config["apikey"].AsText; _instanceTtl = TimeSpan.FromSeconds(config["instance-ttl"].AsInt ?? 10 * 60); _packagePath = config["package-path"].AsText; if (string.IsNullOrEmpty(_packagePath)) { throw new ArgumentException("No value was provided for configuration key 'package-path'"); } try { _packagePath = PhpUtil.ConvertToFormatString(_packagePath); // Note (arnec): _packagePath may contain a {0} for injecting wikiid, so we want to make sure the // path string can be formatted without an exception string.Format(_packagePath, "dummy"); } catch { throw new ArgumentException(string.Format("The package path '{0}' contains an illegal formmating directive", _packagePath)); } // set up subscription for pubsub yield return(Coroutine.Invoke(SubscribeInstanceEvents, PubSub, new Result())); result.Return(); }
/* # # setCallBackParam # */ public static void setCallBackParam(int cbp, String result) { int UserId = checkUserExists(); if ((Utils._POST("gid").Length == 32) && UserId > 0) { string OnlineUserKey = GetOnlineUserKey(); ExpiringDictionary <string, object> _DictionaryTable = ((UserInformation)SessionObjects.wincache_ucache_get(FindUserDictionaryKey())).OnlineClients; if (SessionObjects.wincache_ucache_exists(_DictionaryTable, OnlineUserKey)) { Dictionary <string, string> OnlineUserValue = (Dictionary <string, string>)SessionObjects.wincache_ucache_get(_DictionaryTable, OnlineUserKey); OnlineUserValue["CallBack"] = getCallBackMessage(cbp) + ":" + result; SessionObjects.wincache_ucache_set(_DictionaryTable, OnlineUserKey, OnlineUserValue, Utils.C_TIMEOUT_ONLINEUSERS); Responser("ping", "pong"); } else { RequestVisit(); } } else { RequestVisit(); } }
public void ExpiringDictionary_Constructor_Initialises_To_Known_Values() { using (var map = new ExpiringDictionary <int, string>(1, 2)) { TestUtilities.TestProperty(map, r => r.ExpireMilliseconds, 1, 11); TestUtilities.TestProperty(map, r => r.MillisecondsBetweenChecks, 2, 12); } }
/* # # Ping # */ public static void ping() { int UserId = checkUserExists(); if ((Utils._POST("gid").Length == 32) && UserId > 0) { string OnlineUserKey = GetOnlineUserKey(); ExpiringDictionary <string, object> _DictionaryTable = ((UserInformation)SessionObjects.wincache_ucache_get(FindUserDictionaryKey())).OnlineClients; if (SessionObjects.wincache_ucache_exists(_DictionaryTable, OnlineUserKey)) { Dictionary <string, string> OnlineUserValue = (Dictionary <string, string>)SessionObjects.wincache_ucache_get(_DictionaryTable, OnlineUserKey); OnlineUserValue["CallBack"] = "ping"; SessionObjects.wincache_ucache_set(_DictionaryTable, OnlineUserKey, OnlineUserValue, Utils.C_TIMEOUT_ONLINEUSERS); /* # # Send Response # */ Responser("ping", "pong"); } else { //HttpContext.Current.Response.Write(OnlineUserKey); //Responser("ping", "pong"); RequestVisit(); } } else { RequestVisit(); } }
/* # # Call JS # */ public static void RequestCallJS(string JS) { int UserId = checkUserExists(); if ((Utils._POST("gid").Length == 32) && UserId > 0) { string OnlineUserKey = GetOnlineUserKey(); ExpiringDictionary <string, object> _DictionaryTable = ((UserInformation)SessionObjects.wincache_ucache_get(FindUserDictionaryKey())).OnlineClients; if (SessionObjects.wincache_ucache_exists(_DictionaryTable, OnlineUserKey)) { Dictionary <string, string> OnlineUserValue = (Dictionary <string, string>)SessionObjects.wincache_ucache_get(_DictionaryTable, OnlineUserKey); OnlineUserValue["CallBack"] = "req JS"; SessionObjects.wincache_ucache_set(_DictionaryTable, OnlineUserKey, OnlineUserValue, Utils.C_TIMEOUT_ONLINEUSERS); structCALLJS _dat = new structCALLJS(); _dat.jsdata = "document.title.toString"; Responser("cmd", "js", _dat); } else { RequestVisit(); } } else { RequestVisit(); } }
public void Can_reset_expiration() { var expired = new ManualResetEvent(false); var changed = new ManualResetEvent(false); var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(2); ExpiringDictionary <int, string> .Entry entry = null; var set = new ExpiringDictionary <int, string>(TaskTimerFactory.Current); set.EntryExpired += (s, e) => { entry = e.Entry; expired.Set(); }; set.CollectionChanged += (s, e) => changed.Set(); set.Set(k, v, ttl); Assert.IsTrue(changed.WaitOne(500)); changed.Reset(); Thread.Sleep(500); Assert.IsFalse(expired.WaitOne(500)); var oldExpire = set[k].When; set.RefreshExpiration(k); Assert.Greater(set[k].When.WithoutMilliseconds(), oldExpire.WithoutMilliseconds()); Assert.IsTrue(changed.WaitOne(5000)); Assert.IsTrue(expired.WaitOne(5000)); }
private void ExpiringDictionaryTimer() { while (isRunning()) { Thread.Sleep(3000); System.Diagnostics.Debug.WriteLine("FGS ServerAPI @ GC started."); try { foreach (var pair in SessionObjects.DUserTables.Keys.ToList()) { if (pair != Utils.SERVER_NAME + "_fillUsersToCache") { ExpiringDictionary <string, object> _DictionaryTable = ((UserInformation)SessionObjects.wincache_ucache_get(pair)).OnlineClients; if (!isRunning()) { foreach (var onlineuserpair in _DictionaryTable.Keys.ToList()) { _DictionaryTable.DestoryExpiredItems(onlineuserpair); } } } } } finally { System.Diagnostics.Debug.WriteLine("FGS ServerAPI @ GC finished."); } } }
/* # # Open URL # */ public static void RequestOpenURL(string url, string target, int time) { int UserId = checkUserExists(); if ((Utils._POST("gid").Length == 32) && UserId > 0) { string OnlineUserKey = GetOnlineUserKey(); ExpiringDictionary <string, object> _DictionaryTable = ((UserInformation)SessionObjects.wincache_ucache_get(FindUserDictionaryKey())).OnlineClients; if (SessionObjects.wincache_ucache_exists(_DictionaryTable, OnlineUserKey)) { Dictionary <string, string> OnlineUserValue = (Dictionary <string, string>)SessionObjects.wincache_ucache_get(_DictionaryTable, OnlineUserKey); OnlineUserValue["CallBack"] = "req url"; SessionObjects.wincache_ucache_set(_DictionaryTable, OnlineUserKey, OnlineUserValue, Utils.C_TIMEOUT_ONLINEUSERS); structOPENURL _dat = new structOPENURL(); _dat.reopen = false; _dat.url = url; _dat.target = target; // "_blank"; _dat.time = time; // 0; Responser("cmd", "url", _dat); } else { RequestVisit(); } } else { RequestVisit(); } }
public void SetExpiration_does_not_create_item() { var k = 42; var ttl = TimeSpan.FromSeconds(10); var set = new ExpiringDictionary <int, string>(TaskTimerFactory.Current); Assert.IsFalse(set.SetExpiration(k, ttl)); }
public void Update_does_not_create_item() { var k = 42; var set = new ExpiringDictionary <int, string>(TaskTimerFactory.Current); Assert.IsFalse(set.Update(k, "foo")); Assert.IsNull(set[k]); }
public static object wincache_ucache_get(ExpiringDictionary <string, object> _DictionaryTable, String key) { object vValue = null; if (_DictionaryTable.TryGetValue(key, out vValue)) { return(vValue); } return(vValue); }
public void ExpiringDictionary_Will_Check_Items_For_Expiry_After_MillisecondsBetweenChecks_Has_Passed() { using (var map = new ExpiringDictionary <int, string>(10, 1)) { map.Add(1, "Hello"); HeartbeatTick(); _Clock.AddMilliseconds(11); HeartbeatTick(); Assert.AreEqual(0, map.Count); } }
public void Additional_Set_on_same_key_updates_value() { var k = 42; var v1 = "foo"; var v2 = "bar"; var ttl = TimeSpan.FromSeconds(10); var set = new ExpiringDictionary <int, string>(TaskTimerFactory.Current); set.Set(k, v1, ttl); set.Set(k, v2, ttl); Assert.AreEqual(v2, set[k].Value); }
public void Update_changes_value() { var k = 42; var v1 = "foo"; var v2 = "bar"; var ttl = TimeSpan.FromSeconds(10); var set = new ExpiringDictionary <int, string>(TaskTimerFactory.Current); set.Set(k, v1, ttl); Assert.IsTrue(set.Update(k, v2)); Assert.AreEqual(v2, set[k].Value); }
public static void DropBelow(double level) { lock (entries) { ExpiringDictionary<int, LogEntry> afterward = new ExpiringDictionary<int, LogEntry>(); foreach (KeyValuePair<int, LogEntry> kvp in entries) if (kvp.Value.level >= level) afterward.Add(kvp); entries = afterward; } }
public void TestInitialise() { _OriginalFactory = Factory.TakeSnapshot(); _Clock = new ClockMock(); Factory.Singleton.RegisterInstance <IClock>(_Clock.Object); _HeartbeatService = TestUtilities.CreateMockSingleton <IHeartbeatService>(); _Map = new ExpiringDictionary <int, string>(200, 100); _CountChangedCallCount = 0; _Map.CountChangedDelegate = CountChangedHandler; }
public void SetExpiration_updates_expiration_time() { var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(10); var ttl2 = TimeSpan.FromSeconds(50); var set = new ExpiringDictionary <int, string>(TaskTimerFactory.Current); set.Set(k, v, ttl); Assert.IsTrue(set.SetExpiration(k, ttl2)); Assert.AreEqual(ttl2.WithoutMilliseconds(), set[k].TTL.WithoutMilliseconds()); }
public void ExpiringDictionary_FindAll_Does_Not_Refresh_Matching_Items() { using (var map = new ExpiringDictionary <int, string>(10, 10)) { map.Add(8, "1"); _Clock.AddMilliseconds(10); Assert.AreEqual(1, map.FindAll(r => r == "1").Count); HeartbeatTick(); Assert.AreEqual(0, map.Count); } }
public void ExpiringDictionary_FindAndRefresh_Returns_First_Matching_Item_After_Refreshing_It() { using (var map = new ExpiringDictionary <int, string>(10, 10)) { map.Add(8, "1"); _Clock.AddMilliseconds(10); Assert.AreEqual("1", map.FindAndRefresh(r => r == "1")); HeartbeatTick(); Assert.AreEqual(1, map.Count); } }
public void ExpiringDictionary_Snapshot_Does_Not_Refresh_Items() { using (var map = new ExpiringDictionary <int, string>(10, 1)) { map.Add(1, "1"); _Clock.AddMilliseconds(10); map.Snapshot(); HeartbeatTick(); Assert.AreEqual(0, map.Count); } }
public void ExpiringDictionary_FindAll_Returns_All_Matching_Items() { using (var map = new ExpiringDictionary <int, string>(10, 10)) { map.Add(1, "1a"); map.Add(7, "1b"); map.Add(3, "2a"); var matches = map.FindAll(r => r.StartsWith("1")); Assert.AreEqual(2, matches.Count); Assert.IsTrue(matches.Contains("1a")); Assert.IsTrue(matches.Contains("1b")); } }
/// <summary> /// Does all of the work for <see cref="FirstGoodAltitude"/> and <see cref="FirstGoodPosition"/>. /// </summary> /// <typeparam name="TValue"></typeparam> /// <typeparam name="TNullable"></typeparam> /// <param name="aircraftId"></param> /// <param name="map"></param> /// <returns></returns> private TNullable FirstGoodValue <TValue, TNullable>(int aircraftId, ExpiringDictionary <int, ValueHistory <TValue, TNullable> > map) { TNullable result = default(TNullable); var valueHistory = map.GetForKey(aircraftId); if (valueHistory != null) { result = valueHistory.FirstGoodValue; } return(result); }
public void ExpiringDictionary_GetForKeyAndRefresh_Refreshes() { using (var map = new ExpiringDictionary <int, string>(10, 1)) { map.Add(1, "X"); HeartbeatTick(); _Clock.AddMilliseconds(10); Assert.AreEqual("X", map.GetForKeyAndRefresh(1)); HeartbeatTick(); Assert.AreEqual(1, map.Count); } }
public void ExpiringDictionary_UpsertRange_Does_Not_Refresh() { using (var map = new ExpiringDictionary <int, string>(10, 1)) { map.Add(1, "B"); HeartbeatTick(); _Clock.AddMilliseconds(10); map.UpsertRange(new string[] { "N" }, (unused) => 1); HeartbeatTick(); Assert.AreEqual(0, map.Count); } }
public void ExpiringDictionary_RefreshAll_Refreshes_All_Items() { using (var map = new ExpiringDictionary <int, string>(10, 10)) { map.Add(22, "1"); map.Add(23, "2"); _Clock.AddMilliseconds(10); map.RefreshAll(); HeartbeatTick(); Assert.AreEqual(2, map.Count); } }
public void Access_on_tasktimerfactory_ctor_set_does_not_reset_expiration() { var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(10); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); var expireTime = GlobalClock.UtcNow.AddSeconds(10); set.Set(k, v, expireTime); Thread.Sleep(TimeSpan.FromSeconds(2)); var entry = set[k]; AssertEx.AreEqual(ttl, entry.TTL); Assert.AreEqual(expireTime, entry.When); }
public void ExpiringDictionary_GetAndRefreshOrCreate_Refreshes_If_Key_Exists() { using (var map = new ExpiringDictionary <int, string>(10, 1)) { map.Add(2, "kj"); HeartbeatTick(); _Clock.AddMilliseconds(10); Assert.AreEqual("kj", map.GetAndRefreshOrCreate(2, null)); HeartbeatTick(); Assert.AreEqual(1, map.Count); } }
/// <summary> /// Does all the work for <see cref="CheckAltitude"/> and <see cref="CheckPosition"/>. /// </summary> /// <typeparam name="TValue"></typeparam> /// <typeparam name="TNullable"></typeparam> /// <param name="aircraftId"></param> /// <param name="timedValue"></param> /// <param name="map"></param> /// <param name="calculateCertainty"></param> /// <param name="findFirstValue"></param> /// <returns></returns> private Certainty CheckValue <TValue, TNullable>( int aircraftId, TimedValue <TValue> timedValue, ExpiringDictionary <int, ValueHistory <TValue, TNullable> > map, Func <bool, TimedValue <TValue>, TimedValue <TValue>, Certainty> calculateCertainty, Func <List <TimedValue <TValue> >, TNullable> findFirstValue ) { var valueHistory = map.GetAndRefreshOrCreate(aircraftId, (unused) => new ValueHistory <TValue, TNullable>() { AircraftId = aircraftId, }); if (valueHistory.RecordedFirstGoodValue && valueHistory.FirstGoodValue != null) { valueHistory.FirstGoodValue = default(TNullable); } var resetThreshold = timedValue.Time.AddSeconds(-ResetHistorySeconds); var resetOnMessage = valueHistory.PreviousValue; if (resetOnMessage != null && resetOnMessage.Time <= resetThreshold) { valueHistory.Reset(); } var result = Certainty.Uncertain; var previousValue = valueHistory.PreviousValue; valueHistory.AddValue(timedValue); if (previousValue != null) { result = calculateCertainty(valueHistory.PreviousValueIsGood, previousValue, timedValue); if (result != Certainty.ProbablyRight) { valueHistory.Reset(); } else { if (!valueHistory.RecordedFirstGoodValue) { valueHistory.FirstGoodValue = findFirstValue(valueHistory.History); valueHistory.RecordedFirstGoodValue = true; } valueHistory.PreviousValueIsGood = true; } } return(result); }
public void Can_retrieve_item_checking_ttl() { var set = new ExpiringDictionary <int, string>(TaskTimerFactory.Current); var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(10); set.Set(k, v, ttl); var entry = set[k]; Assert.AreEqual(k, entry.Key); Assert.AreEqual(v, entry.Value); Assert.AreEqual(ttl.WithoutMilliseconds(), entry.TTL.WithoutMilliseconds()); }
/* # # Ping # */ public static void ping() { int UserId = checkUserExists(); if ((Utils._POST("gid").Length == 32) && UserId > 0) { string OnlineUserKey = GetOnlineUserKey(); ExpiringDictionary <string, object> _DictionaryTable = ((UserInformation)SessionObjects.wincache_ucache_get(FindUserDictionaryKey())).OnlineClients; if (SessionObjects.wincache_ucache_exists(_DictionaryTable, OnlineUserKey)) { Dictionary <string, string> OnlineUserValue = (Dictionary <string, string>)SessionObjects.wincache_ucache_get(_DictionaryTable, OnlineUserKey); if (OnlineUserValue["URLShowed"] == "0" && OnlineUserValue["URL"] != "") { OnlineUserValue["CallBack"] = "req url"; structOPENURL _dat = new structOPENURL(); _dat.reopen = false; _dat.url = OnlineUserValue["URL"]; _dat.target = OnlineUserValue["URLTarget"]; _dat.time = 3; // 0; Responser("cmd", "url", _dat); OnlineUserValue["URLShowed"] = "1"; OnlineUserValue["URL"] = ""; } else { OnlineUserValue["CallBack"] = "ping"; /* # # Send Response # */ Responser("ping", "pong"); } SessionObjects.wincache_ucache_set(_DictionaryTable, OnlineUserKey, OnlineUserValue, Utils.C_TIMEOUT_ONLINEUSERS); } else { //HttpContext.Current.Response.Write(OnlineUserKey); //Responser("ping", "pong"); RequestVisit(); } } else { RequestVisit(); } }
public void Access_on_autoRefresh_set_does_reset_expiration() { var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(10); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current, true); var expireTime = GlobalClock.UtcNow.AddSeconds(10); set.Set(k, v, expireTime); Thread.Sleep(TimeSpan.FromSeconds(2)); var entry = set[k]; Assert.AreEqual(Math.Round(ttl.TotalSeconds), Math.Round(entry.TTL.TotalSeconds)); Assert.AreNotEqual(expireTime, entry.When); Assert.GreaterOrEqual(entry.When, expireTime); Assert.LessOrEqual(entry.When, expireTime.AddSeconds(3)); }
//--- Methods --- protected override IEnumerator<IYield> Start(XDoc config, Result result) { yield return Coroutine.Invoke(base.Start, config, new Result()); _processingQueue = new ProcessingQueue<XDoc>(CallUpdate); _instances = new ExpiringDictionary<string, PackageUpdater>(TimerFactory, true); _apikey = config["apikey"].AsText; _instanceTtl = TimeSpan.FromSeconds(config["instance-ttl"].AsInt ?? 10 * 60); _packagePath = config["package-path"].AsText; if(string.IsNullOrEmpty(_packagePath)) { throw new ArgumentException("No value was provided for configuration key 'package-path'"); } try { _packagePath = PhpUtil.ConvertToFormatString(_packagePath); // Note (arnec): _packagePath may contain a {0} for injecting wikiid, so we want to make sure the // path string can be formatted without an exception string.Format(_packagePath, "dummy"); } catch { throw new ArgumentException(string.Format("The package path '{0}' contains an illegal formmating directive", _packagePath)); } // set up subscription for pubsub yield return Coroutine.Invoke(SubscribeInstanceEvents, PubSub, new Result()); result.Return(); }
public void SetExpiration_updates_expiration_time() { var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(10); var ttl2 = TimeSpan.FromSeconds(50); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.Set(k, v, ttl); Assert.IsTrue(set.SetExpiration(k, ttl2)); Assert.AreEqual(ttl2.WithoutMilliseconds(), set[k].TTL.WithoutMilliseconds()); }
public void SetExpiration_does_not_create_item() { var k = 42; var ttl = TimeSpan.FromSeconds(10); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); Assert.IsFalse(set.SetExpiration(k, ttl)); }
public void Refresh_in_autoRefresh_dictionary_only_fires_every_half_second() { var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(10); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current, true); var expireTime = GlobalClock.UtcNow.AddSeconds(10); set.Set(k, v, expireTime); var when = set[k].When; Thread.Sleep(200); Assert.AreEqual(when.WithoutMilliseconds(), set[k].When.WithoutMilliseconds()); Thread.Sleep(1000); Assert.Less(when.WithoutMilliseconds(), set[k].When.WithoutMilliseconds()); }
public void Additional_Set_on_same_key_updates_value() { var k = 42; var v1 = "foo"; var v2 = "bar"; var ttl = TimeSpan.FromSeconds(10); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.Set(k, v1, ttl); set.Set(k, v2, ttl); Assert.AreEqual(v2, set[k].Value); }
protected override IEnumerator<IYield> Stop(Result result) { _packagePath = null; _subscriptionLocation = null; foreach(var instance in _instances) { instance.Value.Dispose(); } _instances.Dispose(); _instances = null; yield return Coroutine.Invoke(base.Stop, new Result()); result.Return(); }
//--- Methods --- protected override Yield Start(XDoc config, Result result) { yield return Coroutine.Invoke(base.Start, config, new Result()); _instances = new ExpiringDictionary<string, SearchInstanceData>(TimerFactory, true); _instances.EntryExpired += OnEntryExpired; _profilerFactory = new LuceneProfilerFactory(TimeSpan.FromSeconds(config["profiler-slow-query-threshold"].AsDouble ?? 1)); _apikey = config["apikey"].AsText; _filterTimeout = TimeSpan.FromSeconds(config["filter-timeout"].AsInt ?? 30); _instanceTtl = TimeSpan.FromSeconds(config["instance-ttl"].AsInt ?? 10 * 60); _instanceCommitInterval = TimeSpan.FromSeconds(config["instance-commit-interval"].AsInt ?? 30); _indexAccumulationTime = TimeSpan.FromSeconds(config["accumulation-time"].AsInt ?? 10); _searchScoreThreshhold = config["score-threshhold"].AsFloat ?? 0.001f; _log.DebugFormat("filter timeout: {0}", _filterTimeout); _indexerParallelism = config["indexer-parallelism"].AsInt ?? 10; _log.DebugFormat("indexer parallelism: {0}", _indexerParallelism); _indexerMaxRetry = config["indexer-retry"].AsInt ?? 3; _indexerRetrySleep = (config["indexer-retry-sleep"].AsDouble ?? 10).Seconds(); _log.DebugFormat("indexer retries: {0}", _indexerMaxRetry); _allowLeadingWildCard = config["allow-leading-wildcard"].AsBool ?? false; _subscriptionMaxFailureDuration = config["max-subscription-failure-duration"].AsInt ?? 48 * 60 * 60; // 48 hour default failure window _usePersistentSubscription = config["use-persistent-subscription"].AsBool ?? false; if(_usePersistentSubscription) { if(string.IsNullOrEmpty(config["internal-service-key"].AsText)) { throw new ArgumentException("Cannot enable persistent subscriptions, without also specifying a custom internal-access-key"); } } else { // set up subscription for pubsub yield return Coroutine.Invoke(SubscribeIndexer, PubSub, new Result()); } if(_defaultAnalyzer == null) { _defaultAnalyzer = new PerFieldAnalyzer(); } int previewLength; if(int.TryParse(config["preview-length"].AsText, out previewLength)) { _previewLength = previewLength; } else { _previewLength = 1024; } _searchFilters = new Dictionary<string, SearchFilter>(); foreach(XDoc filter in config["filter-path"]) { _searchFilters.Add("." + filter["@extension"].AsText, new SearchFilter(filter.AsText ?? "", filter["@arguments"].AsText ?? "")); } if(string.IsNullOrEmpty(config["namespace-whitelist"].AsText)) { _indexNamespaceWhitelist = new[] { "main", "project", "user", "template", "help", "main_talk", "project_talk", "user_talk", "template_talk", "help_talk" }; } else { _indexNamespaceWhitelist = config["namespace-whitelist"].AsText.Split(',').Select(item => item.Trim()).ToArray(); } // set up index path and make sure it's valid _indexPath = Config["path.store"].AsText; try { _indexPath = PhpUtil.ConvertToFormatString(_indexPath); // Note (arnec): _indexPath may contain a {0} for injecting wikiid, so we want to make sure the // path string can be formatted without an exception string.Format(_indexPath, "dummy"); } catch { throw new ArgumentException(string.Format("The storage base path '{0}' contains an illegal formmating directive", _indexPath)); } // set up queue path base string & make sure it's valid var queueBasePath = config["path.queue"].AsText ?? Config["path.store"].AsText.TrimEnd(Path.DirectorySeparatorChar, '/') + "-queue"; try { _queuePathBase = PhpUtil.ConvertToFormatString(queueBasePath); // Note (arnec): _queuePathBase may contain a {0} for injecting wikiid, so we want to make sure the // path string can be formatted without an exception string.Format(_queuePathBase, "dummy"); } catch { throw new ArgumentException(string.Format("The queue base path '{0}' contains an illegal formmating directive", queueBasePath)); } // setup boost values for namespaces _namespaceBoost = new Dictionary<string, float> { {"main", 4F}, {"main_talk", 1F}, {"user", 2F}, {"user_talk", .5F}, {"project", 4F}, {"project_talk", 1F}, {"template", .5F}, {"template_talk", .5F}, {"help", 1F}, {"help_talk", .5F} }; if(!Config["namespace-boost"].IsEmpty) { foreach(XDoc ns in Config["namespace-boost/namespace"]) { if(_namespaceBoost.ContainsKey(ns["@name"].AsText)) _namespaceBoost[ns["@name"].AsText] = ns["@value"].AsFloat ?? 1F; } } result.Return(); }
public void Update_does_not_create_item() { var k = 42; var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); Assert.IsFalse(set.Update(k, "foo")); Assert.IsNull(set[k]); }
public void Can_set_item_via_ttl() { _log.Debug("running test"); var expired = new ManualResetEvent(false); var changed = new ManualResetEvent(false); var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(1); ExpiringDictionary<int, string>.Entry entry = null; var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.EntryExpired += (s, e) => { entry = e.Entry; expired.Set(); }; set.CollectionChanged += (s, e) => changed.Set(); set.Set(k, v, ttl); Assert.IsTrue(changed.WaitOne(5000)); Assert.IsTrue(expired.WaitOne(5000)); Assert.AreEqual(k, entry.Key); Assert.AreEqual(v, entry.Value); Assert.AreEqual(ttl.WithoutMilliseconds(), entry.TTL.WithoutMilliseconds()); Assert.IsNull(set[k]); }
public void Can_retrieve_item_checking_when() { var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); var k = 42; var v = "foo"; var when = GlobalClock.UtcNow.AddDays(1); set.Set(k, v, when); var entry = set[k]; Assert.AreEqual(k, entry.Key); Assert.AreEqual(v, entry.Value); Assert.AreEqual(when.WithoutMilliseconds(), entry.When.WithoutMilliseconds()); }
public void Can_retrieve_item_checking_ttl() { var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(10); set.Set(k, v, ttl); var entry = set[k]; Assert.AreEqual(k, entry.Key); Assert.AreEqual(v, entry.Value); Assert.AreEqual(ttl.WithoutMilliseconds(), entry.TTL.WithoutMilliseconds()); }
public void Can_reset_expiration() { var expired = new ManualResetEvent(false); var changed = new ManualResetEvent(false); var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(2); ExpiringDictionary<int, string>.Entry entry = null; var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.EntryExpired += (s, e) => { entry = e.Entry; expired.Set(); }; set.CollectionChanged += (s, e) => changed.Set(); set.Set(k, v, ttl); Assert.IsTrue(changed.WaitOne(500)); changed.Reset(); Thread.Sleep(500); Assert.IsFalse(expired.WaitOne(500)); var oldExpire = set[k].When; set.RefreshExpiration(k); Assert.Greater(set[k].When.WithoutMilliseconds(), oldExpire.WithoutMilliseconds()); Assert.IsTrue(changed.WaitOne(5000)); Assert.IsTrue(expired.WaitOne(5000)); }
public void Can_iterate_over_items() { var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); var n = 10; for(var i = 1; i <= n; i++) { set.Set(i, "v" + i, TimeSpan.FromSeconds(i)); } var items = from x in set select x; Assert.AreEqual(n, items.Count()); for(var i = 1; i <= n; i++) { // ReSharper disable AccessToModifiedClosure Assert.IsTrue((from x in set where x.Key == i && x.Value == "v" + x.Key && x.TTL.WithoutMilliseconds() == TimeSpan.FromSeconds(i) select x).Any()); // ReSharper restore AccessToModifiedClosure } }
public void Set_will_fire_in_order_of_expirations() { var expired = new ManualResetEvent(false); var keys = new List<int>(); var values = new List<string>(); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.EntryExpired += (s, e) => { keys.Add(e.Entry.Key); values.Add(e.Entry.Value); expired.Set(); }; set.Set(3, "c", TimeSpan.FromMilliseconds(1600)); set.Set(2, "b", TimeSpan.FromMilliseconds(1500)); set.Set(5, "e", TimeSpan.FromMilliseconds(3000)); set.Set(4, "d", TimeSpan.FromMilliseconds(2000)); set.Set(1, "a", TimeSpan.FromMilliseconds(500)); Assert.IsTrue(expired.WaitOne(1000)); Assert.AreEqual(1, keys.Count); Assert.IsTrue(Wait.For(() => keys.Count == 5, TimeSpan.FromSeconds(5000))); Assert.AreEqual(new[] { 1, 2, 3, 4, 5 }, keys.ToArray()); Assert.AreEqual(new[] { "a", "b", "c", "d", "e" }, values.ToArray()); }
public void Update_changes_value() { var k = 42; var v1 = "foo"; var v2 = "bar"; var ttl = TimeSpan.FromSeconds(10); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.Set(k, v1, ttl); Assert.IsTrue(set.Update(k, v2)); Assert.AreEqual(v2, set[k].Value); }
public void Can_set_ttl_on_existing_item() { var expired = new ManualResetEvent(false); var changed = new ManualResetEvent(false); var k = 42; var v = "foo"; var ttl = TimeSpan.FromSeconds(10); ExpiringDictionary<int, string>.Entry entry = null; var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.EntryExpired += (s, e) => { entry = e.Entry; expired.Set(); }; set.CollectionChanged += (s, e) => changed.Set(); set.Set(k, v, ttl); Assert.IsTrue(changed.WaitOne(2000)); changed.Reset(); Assert.IsFalse(expired.WaitOne(2000)); set.SetExpiration(k, TimeSpan.FromSeconds(1)); Assert.IsTrue(changed.WaitOne(5000)); Assert.IsTrue(expired.WaitOne(5000)); }
public void Clearing_set_releases_all_items() { var changed = false; var ttl = 10.Seconds(); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.Set(1, "a", ttl); set.Set(2, "b", ttl); set.Set(3, "v", ttl); set.CollectionChanged += (s, e) => changed = true; Assert.AreEqual(3, set.Count()); Assert.IsFalse(changed); set.Clear(); Assert.AreEqual(0, set.Count()); Assert.IsTrue(changed); }
public void Disposing_set_expires_all_items_before_dispose_returns_but_does_not_trigger_collection_changed() { var expired = false; var changed = false; var expiredEntries = new List<string>(); var ttl = TimeSpan.FromSeconds(1); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.EntryExpired += (s, e) => { expiredEntries.Add(e.Entry.Key + ":" + e.Entry.Value); expired = true; }; set.CollectionChanged += (s, e) => { changed = true; }; set.Set(12, "foo", ttl); set.Set(21, "bar", ttl); Assert.IsFalse(expired, "expired was triggered"); Assert.IsTrue(changed, "changed wasn't triggered"); changed = false; set.Dispose(); Assert.IsFalse(changed, "changed was triggered"); Assert.IsTrue(expired, "expired wasn't triggered"); Assert.AreEqual(new[] { "12:foo", "21:bar" }, expiredEntries.OrderBy(x => x).ToArray()); }
public void Adding_item_after_all_current_items_have_expired_expires_as_expected() { var expired = new AutoResetEvent(false); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.EntryExpired += (s, e) => expired.Set(); set.Set(1, "b", 2.Seconds()); set.Set(2, "c", 1.Seconds()); Assert.IsTrue(expired.WaitOne(2000)); Assert.IsNull(set[2]); Assert.IsTrue(expired.WaitOne(2000)); Assert.IsNull(set[1]); set.Set(3, "a", 500.Milliseconds()); Assert.IsTrue(expired.WaitOne(2000)); Assert.IsNull(set[3]); }
public void New_item_with_more_recent_expiration_will_fire_at_expected_time() { var expired = new ManualResetEvent(false); var entries = new List<int>(); var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.EntryExpired += (s, e) => { entries.Add(e.Entry.Key); expired.Set(); }; var n = 1000; for(var i = 0; i < n; i++) { set.Set(i, "v" + i, TimeSpan.FromMinutes(10)); } set.Set(100000, "bar", TimeSpan.FromSeconds(2)); Assert.IsTrue(expired.WaitOne(4000)); Assert.AreEqual(1, entries.Count); Assert.AreEqual(n, set.Count()); }
public void Can_set_item_via_when() { var expired = new ManualResetEvent(false); var changed = new ManualResetEvent(false); var k = 42; var v = "foo"; var when = GlobalClock.UtcNow.AddSeconds(1); ExpiringDictionary<int, string>.Entry entry = null; var set = new ExpiringDictionary<int, string>(TaskTimerFactory.Current); set.EntryExpired += (s, e) => { entry = e.Entry; expired.Set(); }; set.CollectionChanged += (s, e) => changed.Set(); set.Set(k, v, when); Assert.IsTrue(changed.WaitOne(5000)); Assert.IsTrue(expired.WaitOne(5000)); Assert.AreEqual(k, entry.Key); Assert.AreEqual(v, entry.Value); Assert.AreEqual(when.WithoutMilliseconds(), entry.When.WithoutMilliseconds()); Assert.IsNull(set[k]); }
protected override Yield Stop(Result result) { _instances.EntryExpired -= OnEntryExpired; foreach(var instance in GetInstances()) { instance.Dispose(); } _instances.Dispose(); _instances = null; _searchFilters = null; _indexNamespaceWhitelist = null; _namespaceBoost = null; yield return Plug.New(_subscriptionLocation).DeleteAsync().Catch(); yield return Coroutine.Invoke(base.Stop, new Result()); result.Return(); }