{"id":3401,"date":"2015-03-18T13:00:43","date_gmt":"2015-03-18T13:00:43","guid":{"rendered":"http:\/\/writeasync.net\/?p=3401"},"modified":"2015-03-18T04:02:27","modified_gmt":"2015-03-18T04:02:27","slug":"wake-up","status":"publish","type":"post","link":"http:\/\/writeasync.net\/?p=3401","title":{"rendered":"Wake up!"},"content":{"rendered":"<p>In <a href=\"http:\/\/www.manning.com\/koskela2\/\">Effective Unit Testing: A guide for Java developers<\/a>, author <a href=\"http:\/\/lassekoskela.com\/\">Lasse Koskela<\/a> writes about the scourge of <a href=\"http:\/\/www.softwaretestingmagazine.com\/knowledge\/unit-testing-in-java-a-sleeping-snail\/\">the sleeping snail<\/a> &#8212; slow tests littered with calls to <a href=\"http:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/lang\/Thread.html#sleep(long)\"><code>Thread.sleep<\/code><\/a>. His suggested alternative is perfectly sound and practical: turn nondeterministic waiting into explicit synchronization with help from primitives like a <a href=\"http:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/util\/concurrent\/CountDownLatch.html\"><code>CountDownLatch<\/code><\/a> (that&#8217;s <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.threading.countdownevent(v=vs.110).aspx\"><code>CountdownEvent<\/code><\/a> for us .NET programmers).<\/p>\n<p>There is however another way that should be used when possible: avoid background threads completely and bring the action right to you. Wake up and take part!<\/p>\n<p>Consider an example of an &#8220;expiring cache.&#8221; Items in the cache have a certain <a href=\"http:\/\/en.wikipedia.org\/wiki\/Time_to_live\">time to live<\/a> after which they are <a href=\"http:\/\/en.wikipedia.org\/wiki\/Cache_algorithms\">evicted<\/a>. A na\u00efve way to implement this would involve direct use of a <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.threading.timer(v=vs.110).aspx\"><code>Timer<\/code><\/a> and some &#8220;sleepy&#8221; unit tests to verify the implementation, like so:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic sealed class ExpiringCache&lt;TKey, TValue&gt;\r\n{\r\n    private readonly ConcurrentDictionary&lt;TKey, ExpiringValue&gt; items;\r\n\r\n    public ExpiringCache()\r\n    {\r\n        this.items = new ConcurrentDictionary&lt;TKey, ExpiringValue&gt;();\r\n    }\r\n\r\n    public void Add(TKey key, TValue value, TimeSpan timeToLive)\r\n    {\r\n        this.items.AddOrUpdate(key, k =&gt; new ExpiringValue(this, k, value, timeToLive), (k, v) =&gt; v);\r\n    }\r\n\r\n    public bool TryGet(TKey key, out TValue value)\r\n    {\r\n        ExpiringValue expiringValue;\r\n        if (!this.items.TryGetValue(key, out expiringValue))\r\n        {\r\n            value = default(TValue);\r\n            return false;\r\n        }\r\n\r\n        value = expiringValue.Value;\r\n        return true;\r\n    }\r\n\r\n    private void Remove(TKey key)\r\n    {\r\n        ExpiringValue value;\r\n        this.items.TryRemove(key, out value);\r\n    }\r\n\r\n    private sealed class ExpiringValue\r\n    {\r\n        private readonly ExpiringCache&lt;TKey, TValue&gt; parent;\r\n        private readonly TKey key;\r\n        private readonly Timer timer;\r\n\r\n        public ExpiringValue(ExpiringCache&lt;TKey, TValue&gt; parent, TKey key, TValue value, TimeSpan timeToLive)\r\n        {\r\n            this.parent = parent;\r\n            this.key = key;\r\n            this.Value = value;\r\n            this.timer = new Timer(Expire, this, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);\r\n            this.timer.Change(timeToLive, Timeout.InfiniteTimeSpan);\r\n        }\r\n\r\n        public TValue Value { get; private set; }\r\n\r\n        private static void Expire(object thisObj)\r\n        {\r\n            ((ExpiringValue)thisObj).Expire();\r\n        }\r\n\r\n        private void Expire()\r\n        {\r\n            this.parent.Remove(this.key);\r\n            this.timer.Dispose();\r\n        }\r\n    }\r\n}\r\n\r\n&#x5B;TestClass]\r\npublic class ExpiringCacheTest\r\n{\r\n    &#x5B;TestMethod]\r\n    public void AddedItemShouldStillExistBeforeExpirationTime()\r\n    {\r\n        ExpiringCache&lt;int, string&gt; cache = new ExpiringCache&lt;int, string&gt;();\r\n        cache.Add(1, &quot;two&quot;, TimeSpan.FromSeconds(1.0d));\r\n\r\n        string value;\r\n        Assert.IsTrue(cache.TryGet(1, out value));\r\n        Assert.AreEqual(&quot;two&quot;, value);\r\n    }\r\n\r\n    &#x5B;TestMethod]\r\n    public void AddedItemShouldNotExistAfterExpirationTime()\r\n    {\r\n        ExpiringCache&lt;int, string&gt; cache = new ExpiringCache&lt;int, string&gt;();\r\n        cache.Add(1, &quot;two&quot;, TimeSpan.FromSeconds(0.5d));\r\n\r\n        Thread.Sleep(1000);\r\n\r\n        string value;\r\n        Assert.IsFalse(cache.TryGet(1, out value));\r\n    }\r\n\r\n    &#x5B;TestMethod]\r\n    public void UpdatedItemShouldNotUpdateValue()\r\n    {\r\n        ExpiringCache&lt;int, string&gt; cache = new ExpiringCache&lt;int, string&gt;();\r\n        cache.Add(1, &quot;two&quot;, TimeSpan.FromSeconds(0.5d));\r\n        cache.Add(1, &quot;three&quot;, TimeSpan.FromSeconds(0.5d));\r\n\r\n        string value;\r\n        Assert.IsTrue(cache.TryGet(1, out value));\r\n        Assert.AreEqual(&quot;two&quot;, value);\r\n    }\r\n\r\n    &#x5B;TestMethod]\r\n    public void UpdatedItemShouldNotUpdateExpirationTime()\r\n    {\r\n        ExpiringCache&lt;int, string&gt; cache = new ExpiringCache&lt;int, string&gt;();\r\n        cache.Add(1, &quot;two&quot;, TimeSpan.FromSeconds(0.5d));\r\n        cache.Add(1, &quot;three&quot;, TimeSpan.FromSeconds(4.0d));\r\n\r\n        Thread.Sleep(1000);\r\n\r\n        string value;\r\n        Assert.IsFalse(cache.TryGet(1, out value));\r\n    }\r\n}\r\n<\/pre>\n<p>This works (well&#8230; most of the time), but it is enormously slow in unit testing terms. The two seconds spent doing absolutely nothing is enough time to run <em>thousands<\/em> of other fast unit tests. If we instead take a page from the async playbook we can gain control of the fabric of time, so to speak. How?<\/p>\n<p>First, let&#8217;s replace the timer with a strategically placed Task.Delay:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nprivate sealed class ExpiringValue\r\n{\r\n    private readonly ExpiringCache&lt;TKey, TValue&gt; parent;\r\n    private readonly TKey key;\r\n    private readonly Task expired;\r\n\r\n    public ExpiringValue(ExpiringCache&lt;TKey, TValue&gt; parent, TKey key, TValue value, TimeSpan timeToLive)\r\n    {\r\n        this.parent = parent;\r\n        this.key = key;\r\n        this.Value = value;\r\n        this.expired = Task.Delay(timeToLive).ContinueWith(this.Expire, TaskContinuationOptions.ExecuteSynchronously);\r\n    }\r\n\r\n    public TValue Value { get; private set; }\r\n\r\n    private void Expire(Task task)\r\n    {\r\n        this.parent.Remove(this.key);\r\n    }\r\n}\r\n<\/pre>\n<p>Nothing much has changed, but this gives us the beginning of an important <a href=\"http:\/\/www.informit.com\/articles\/article.aspx?p=359417&#038;seqNum=2\">test seam<\/a>. It turns out that Task&#8217;s role as a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Futures_and_promises\">promise\/future<\/a> is useful for more than non-blocking I\/O calls. We just need to go one step further and return a Task whose lifetime is under our complete control, and in essence we will become the timekeeper with no need for sleep!<\/p>\n<p>Keeping it simple, we can add a pluggable delay delegate with the same signature as Task.Delay and override the implementation for testing purposes:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic sealed class ExpiringCache&lt;TKey, TValue&gt;\r\n{\r\n    private static readonly Func&lt;Task&gt; DefaultDelay = Task.Delay;\r\n    \/\/ ...\r\n    public ExpiringCache()\r\n    {\r\n        \/\/ ...\r\n        this.Delay = DefaultDelay;\r\n    }\r\n\r\n    public Func&lt;TimeSpan, Task&gt; Delay { get; set; }\r\n    \/\/ ...\r\n    public ExpiringValue(ExpiringCache&lt;TKey, TValue&gt; parent, TKey key, TValue value, TimeSpan timeToLive)\r\n    {\r\n        \/\/ ...\r\n        this.expired = parent.Delay(timeToLive).ContinueWith(this.Expire, TaskContinuationOptions.ExecuteSynchronously);\r\n    }\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<p>With all tests still passing, we can now attack the sleeping giant. First, we&#8217;ll define a test class to simulate a timer event that fires at some future time (defined as an inner class of its only user, ExpiringCacheTest):<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nprivate sealed class AlarmClock\r\n{\r\n    private TaskCompletionSource&lt;bool&gt; tcs;\r\n    private TimeSpan dueTime;\r\n\r\n    public AlarmClock()\r\n    {\r\n    }\r\n\r\n    public Task Set(TimeSpan dueTime)\r\n    {\r\n        this.tcs = new TaskCompletionSource&lt;bool&gt;();\r\n        this.dueTime = dueTime;\r\n        return this.tcs.Task;\r\n    }\r\n\r\n    public TimeSpan Wake()\r\n    {\r\n        this.tcs.SetResult(false);\r\n        return this.dueTime;\r\n    }\r\n}\r\n<\/pre>\n<p>Now let&#8217;s fix the implementation of our two long running tests:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;TestMethod]\r\npublic void AddedItemShouldNotExistAfterExpirationTime()\r\n{\r\n    AlarmClock clock = new AlarmClock(); \r\n    ExpiringCache&lt;int, string&gt; cache = new ExpiringCache&lt;int, string&gt;()\r\n    {\r\n        Delay = clock.Set\r\n    };\r\n\r\n    cache.Add(1, &quot;two&quot;, TimeSpan.FromSeconds(0.5d));\r\n\r\n    TimeSpan dueTime = clock.Wake();\r\n    Assert.AreEqual(TimeSpan.FromSeconds(0.5d), dueTime);\r\n\r\n    string value;\r\n    Assert.IsFalse(cache.TryGet(1, out value));\r\n}\r\n\/\/ ...\r\n&#x5B;TestMethod]\r\npublic void UpdatedItemShouldNotUpdateExpirationTime()\r\n{\r\n    AlarmClock clock = new AlarmClock();\r\n    ExpiringCache&lt;int, string&gt; cache = new ExpiringCache&lt;int, string&gt;()\r\n    {\r\n        Delay = clock.Set\r\n    }; \r\n\r\n    cache.Add(1, &quot;two&quot;, TimeSpan.FromSeconds(0.5d));\r\n    cache.Add(1, &quot;three&quot;, TimeSpan.FromSeconds(4.0d));\r\n\r\n    TimeSpan dueTime = clock.Wake();\r\n    Assert.AreEqual(TimeSpan.FromSeconds(0.5d), dueTime);\r\n\r\n    string value;\r\n    Assert.IsFalse(cache.TryGet(1, out value));\r\n}\r\n<\/pre>\n<p>Basically, the AlarmClock keeps track of what time was set and allows manual control of when we awake. Not only have we eliminated the sleeps, we have eliminated background threads entirely. The call to <code>TaskCompletionSource.SetResult<\/code> runs the continuation which expires the cache item <em>synchronously<\/em> because we strategically specified <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.threading.tasks.taskcontinuationoptions(v=vs.110).aspx\"><code>TaskContinuationOptions.ExecuteSynchronously<\/code><\/a> above.<\/p>\n<p>This approach is simple and noninvasive enough that it leaves no good excuse for sleeping on the job. Try it out and kick your unit test suites into high gear!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Effective Unit Testing: A guide for Java developers, author Lasse Koskela writes about the scourge of the sleeping snail &#8212; slow tests littered with calls to Thread.sleep. His suggested alternative is perfectly sound and practical: turn nondeterministic waiting into&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21,91,41],"tags":[],"class_list":["post-3401","post","type-post","status-publish","format-standard","hentry","category-async","category-design","category-tdd"],"_links":{"self":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/3401","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3401"}],"version-history":[{"count":0,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/3401\/revisions"}],"wp:attachment":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3401"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3401"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3401"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}