Пример #1
0
        public async Task MemoizeAsync_BackgroundRefreshFails_TTLNotExtended()
        {
            var args        = new object[] { "someString" };
            var refreshTask = new TaskCompletionSource <Thing>();

            refreshTask.SetException(new Exception("Boo!!"));
            var dataSource = CreateDataSource(5, refreshTask, 7);

            IMemoizer memoizer = new AsyncMemoizer(new AsyncCache(new ConsoleLog(), Metric.Context("AsyncCache"), new DateTimeImpl(), new EmptyRevokeListener()), new MetadataProvider(), Metric.Context("Tests"));

            // T = 0. No data in cache, should retrieve value from source (5).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

            await Task.Delay(TimeSpan.FromSeconds(2));

            // T = 2. Past refresh time (1s), this triggers refresh in background, should get existing value (5)
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

            await Task.Delay(TimeSpan.FromSeconds(1));

            // T = 3. Background refresh failed, but TTL (4s) not expired yet. Should still give old value (5)
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

            await Task.Delay(TimeSpan.FromSeconds(2));

            // T = 5. We're past the original TTL (4s), and refresh task failed. Items should have been evicted from cache by now.
            // New item (7) should come in.
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(7);
            dataSource.Received(3).ThingifyTaskThing(Arg.Any <string>());
        }
Пример #2
0
        public async Task MemoizeAsync_BackgroundRefreshFails_TTLNotExtended()
        {
            var args        = new object[] { "someString" };
            var refreshTask = new TaskCompletionSource <Thing>();

            refreshTask.SetException(new MissingFieldException("Boo!!"));
            var dataSource = CreateDataSource(870, refreshTask, 1002);

            IMemoizer memoizer = new AsyncMemoizer(new AsyncCache(new ConsoleLog(), Metric.Context("AsyncCache"), new DateTimeImpl(), new EmptyRevokeListener(), () => new RevokeConfig()), new MetadataProvider(), Metric.Context("Tests"));

            // T = 0s. No data in cache, should retrieve value from source (870).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(5, 1, 100))).Id.ShouldBe(870);

            await Task.Delay(TimeSpan.FromSeconds(2));

            // T = 2s. Past refresh time (1s), this triggers refresh in background (that will fail), should get existing value (870)
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(5, 1, 100))).Id.ShouldBe(870);

            await Task.Delay(TimeSpan.FromSeconds(2));

            // T = 4s. Background refresh failed, but TTL (5s) not expired yet. Should still give old value (870) but won't
            // trigger additional background refresh because of very long FailedRefreshDelay that was spcified (100s).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(5, 1, 100))).Id.ShouldBe(870);

            await Task.Delay(TimeSpan.FromSeconds(2));

            // T = 6s. We're past the original TTL (5s), and refresh task failed. Items should have been evicted from cache by now
            // according to 5s expiery from T=0s, not from T=2s of the failed refresh. New item (1002) should come in.
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(5, 1))).Id.ShouldBe(1002);
            dataSource.Received(3).ThingifyTaskThing(Arg.Any <string>());
        }
Пример #3
0
        public async Task MemoizeAsync_CallAfterRefreshTime_TTLNotExpired()
        {
            var dataSource = CreateDataSource(5, 7, 9);
            var args       = new object[] { "someString" };

            IMemoizer memoizer = new AsyncMemoizer(new AsyncCache(new ConsoleLog(), Metric.Context("AsyncCache"), new DateTimeImpl(), new EmptyRevokeListener()), new MetadataProvider(), Metric.Context("Tests"));

            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

            await Task.Delay(TimeSpan.FromSeconds(2));

            // Refresh just triggered, should get old value (5)
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5); // value is not refreshed yet. it is running on background

            await Task.Delay(TimeSpan.FromSeconds(1));

            // Complete refresh task and verify new value
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(7); // value is not refreshed yet. it is running on background

            await Task.Delay(TimeSpan.FromSeconds(2));

            // We're past the original TTL, should still be the refreshed value (7), not another (9).
            // If 9 was returned, it means the data source was accessed again, probably because the TTL expired
            // (it shouldn't, every refresh should extend the TTL).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(7); // new value is expected now
            dataSource.Received(2).ThingifyTaskThing(Arg.Any <string>());
        }
Пример #4
0
        public async Task MemoizeAsync_CallAfterRefreshTime_TTLNotExpired()
        {
            var dataSource = CreateDataSource(5, 7, 9);
            var args       = new object[] { "someString" };

            IMemoizer memoizer = new AsyncMemoizer(new AsyncCache(new ConsoleLog(), Metric.Context("AsyncCache"), new DateTimeImpl(), new EmptyRevokeListener(), () => new RevokeConfig()), new MetadataProvider(), Metric.Context("Tests"));

            // T = 0s. No data in cache, should retrieve value from source (5).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

            await Task.Delay(TimeSpan.FromSeconds(2));

            // T = 2s. Refresh just triggered, should get old value (5).
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(5);

            await Task.Delay(TimeSpan.FromSeconds(0.5));

            // T = 2.5s. Refresh task should have completed by now, verify new value. Should not trigger another refresh.
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(7);

            await Task.Delay(TimeSpan.FromSeconds(2.5));

            // T = 5s. We're past the original TTL (from T=0s) but not past the refreshed TTL (from T=2s). Should still
            // return the refreshed value (7), not another (9). If (9) was returned, it means the data source was accessed
            // again, probably because the TTL expired (it shouldn't, every refresh should extend the TTL). This should also
            // trigger another refresh.
            (await(Task <Thing>) memoizer.Memoize(dataSource, ThingifyTaskThing, args, GetPolicy(4, 1))).Id.ShouldBe(7); // new value is expected now

            dataSource.Received(3).ThingifyTaskThing(Arg.Any <string>());
        }