Beispiel #1
0
 /// <summary>
 /// Initializes a new instance of the
 /// <see cref="DataLoader{TKey, TValue}"/> class.
 /// </summary>
 /// <param name="options">
 /// An options object to configure the behavior of this particular
 /// <see cref="DataLoader{TKey, TValue}"/>.
 /// </param>
 /// <param name="fetch">
 /// A delegate to fetch data batches which will be invoked every time
 /// when trying to setup a new batch request.
 /// </param>
 /// <exception cref="ArgumentNullException">
 /// Throws if <paramref name="options"/> is <c>null</c>.
 /// </exception>
 /// <exception cref="ArgumentNullException">
 /// Throws if <paramref name="fetch"/> is <c>null</c>.
 /// </exception>
 public DataLoader(
     DataLoaderOptions <TKey> options,
     FetchDataDelegate <TKey, TValue> fetch)
     : base(options)
 {
     _fetch = fetch ?? throw new ArgumentNullException(nameof(fetch));
 }
Beispiel #2
0
        private static DataLoaderOptions CreateLocalOptions(DataLoaderOptions options)
        {
            DataLoaderOptions local = options.Copy();

            local.MaxBatchSize = 1;
            return(local);
        }
        public void RemoveEntry()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = async keys =>
                                                       await Task.FromResult(new IResult <string> [0])
                                                       .ConfigureAwait(false);

            var options = new DataLoaderOptions <string>
            {
                Batching = false
            };
            var loader = new DataLoader <string, string>(options, fetch);
            var key    = "Foo";

            loader.Set(key, Task.FromResult("Bar"));

            // act
            IDataLoader <string, string> result = loader.Remove(key);

            // assert
            Task <string> loadResult = loader.LoadAsync(key);

            if (loadResult is IAsyncResult asyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
            }

            Assert.Equal(loader, result);
            Assert.NotNull(loadResult.Exception);
        }
 /// <summary>
 /// Initializes a new instance of the
 /// <see cref="DataLoaderBase{TKey, TValue}"/> class.
 /// </summary>
 /// <param name="options">
 /// A configuration for <c>DataLoaders</c>.
 /// </param>
 /// <exception cref="ArgumentNullException">
 /// Throws if <paramref name="options"/> is <c>null</c>.
 /// </exception>
 protected DataLoaderBase(DataLoaderOptions <TKey> options)
     : this(options, new TaskCache <TValue>(
                options?.CacheSize ?? Defaults.CacheSize,
                options?.SlidingExpiration ??
                Defaults.SlidingExpiration))
 {
 }
        public async Task LoadCollectionResult()
        {
            // arrange
            var expectedResult = Result <string> .Resolve("Bar");

            FetchDataDelegate <string, string> fetch = async k =>
                                                       await Task.FromResult(new[] { expectedResult })
                                                       .ConfigureAwait(false);

            var options = new DataLoaderOptions <string>
            {
                Batching = false
            };
            var loader = new DataLoader <string, string>(options, fetch);
            var keys   = new List <string> {
                "Foo"
            };

            // act
            IReadOnlyList <string> loadResult = await loader
                                                .LoadAsync(keys)
                                                .ConfigureAwait(false);

            // assert
            Assert.Collection(loadResult,
                              v => Assert.Equal(expectedResult.Value, v));
        }
        public async Task DispatchAsyncKeysValuesNotMatching()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = async keys =>
                                                       await Task.FromResult(new IResult <string> [0])
                                                       .ConfigureAwait(false);

            var options = new DataLoaderOptions <string>
            {
                BatchRequestDelay = TimeSpan.FromMinutes(10)
            };
            var loader = new DataLoader <string, string>(options, fetch);

            await Task.Delay(10);

            Task <IReadOnlyList <string> > loadResult = loader.LoadAsync("Foo", "Bar");

            await loader.DispatchAsync().ConfigureAwait(false);

            // act
            Func <Task> verify = () => loadResult;

            // assert
            await Assert.ThrowsAsync <InvalidOperationException>(verify)
            .ConfigureAwait(false);
        }
        public void ConstructorAllProps()
        {
            // act
            var options = new DataLoaderOptions <string>
            {
                AutoDispatching   = false,
                Batching          = false,
                BatchRequestDelay = TimeSpan.FromSeconds(1),
                CacheKeyResolver  = k => k,
                CacheSize         = 1,
                Caching           = false,
                MaxBatchSize      = 1,
                SlidingExpiration = TimeSpan.FromSeconds(10)
            };

            // assert
            Assert.False(options.AutoDispatching);
            Assert.False(options.Batching);
            Assert.Equal(TimeSpan.FromSeconds(1), options.BatchRequestDelay);
            Assert.NotNull(options.CacheKeyResolver);
            Assert.Equal(1, options.CacheSize);
            Assert.False(options.Caching);
            Assert.Equal(1, options.MaxBatchSize);
            Assert.Equal(TimeSpan.FromSeconds(10), options.SlidingExpiration);
        }
        public async Task DispatchAsyncAuto()
        {
            // arrange
            IResult <string> expectedResult = Result <string> .Resolve("Bar");

            FetchDataDelegate <string, string> fetch = async keys =>
                                                       await Task.FromResult(new[] { expectedResult })
                                                       .ConfigureAwait(false);

            var options = new DataLoaderOptions <string>
            {
                BatchRequestDelay = TimeSpan.FromMinutes(10)
            };
            var loader = new DataLoader <string, string>(options, fetch);

            await Task.Delay(10);

            Task <string> loadResult = loader.LoadAsync("Foo");

            // act
            await loader.DispatchAsync().ConfigureAwait(false);

            // assert
            Assert.Equal(expectedResult.Value,
                         await loadResult.ConfigureAwait(false));
        }
        public async Task DispatchAsyncNoBatching()
        {
            // arrange
            IResult <string> expectedResult = Result <string> .Resolve("Bar");

            FetchDataDelegate <string, string> fetch = async keys =>
                                                       await Task.FromResult(new[] { expectedResult })
                                                       .ConfigureAwait(false);

            var options = new DataLoaderOptions <string>
            {
                Batching = false
            };
            var loader = new DataLoader <string, string>(options, fetch);

            // this would block if batching would be enabled
            var loadResult = await loader.LoadAsync("Foo")
                             .ConfigureAwait(false);

            // act
            await loader.DispatchAsync().ConfigureAwait(false);

            // assert
            Assert.Equal(expectedResult.Value, loadResult);
        }
Beispiel #10
0
        public async Task ClearAllEntries()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = async keys =>
                                                       await Task.FromResult(new IResult <string> [0])
                                                       .ConfigureAwait(false);

            var options = new DataLoaderOptions <string>
            {
                Batching = false
            };
            var loader = new DataLoader <string, string>(options, fetch);

            loader.Set("Foo", Task.FromResult("Bar"));
            loader.Set("Bar", Task.FromResult("Baz"));

            // act
            IDataLoader <string, string> result = loader.Clear();

            // assert
            Func <Task> verify = () => loader.LoadAsync("Foo", "Bar");

            Assert.Equal(loader, result);
            await Assert.ThrowsAsync <InvalidOperationException>(verify)
            .ConfigureAwait(false);
        }
Beispiel #11
0
        public void ConstructorEmpty()
        {
            // act
            var options = new DataLoaderOptions <string>();

            // assert
            options.MatchSnapshot();
        }
Beispiel #12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DataLoader{TKey, TValue}"/> class.
 /// </summary>
 /// <param name="batchScheduler">
 /// A scheduler to tell the <c>DataLoader</c> when to dispatch buffered batches.
 /// </param>
 /// <param name="options">
 /// An options object to configure the behavior of this particular
 /// <see cref="DataLoader{TKey, TValue}"/>.
 /// </param>
 /// <exception cref="ArgumentNullException">
 /// Throws if <paramref name="options"/> is <c>null</c>.
 /// </exception>
 protected DataLoaderBase(IBatchScheduler batchScheduler, DataLoaderOptions <TKey>?options)
 {
     _options          = options ?? new DataLoaderOptions <TKey>();
     _cache            = _options.Cache ?? new TaskCache(_options.CacheSize);
     _cacheKeyResolver = _options.CacheKeyResolver ?? ((TKey key) => key);
     _batchScheduler   = batchScheduler;
     _maxBatchSize     = _options.GetBatchSize();
 }
Beispiel #13
0
 public DataLoader(
     IBatchScheduler batchScheduler,
     FetchDataDelegate <TKey, TValue> fetch,
     DataLoaderOptions <TKey>?options)
     : base(batchScheduler, options)
 {
     _fetch = fetch ?? throw new ArgumentNullException(nameof(fetch));
 }
        public void ConstructorEmpty()
        {
            // act
            var options = new DataLoaderOptions();

            // assert
            Assert.Null(options.Cache);
            Assert.True(options.Caching);
            Assert.Equal(1024, options.MaxBatchSize);
            Assert.Null(options.DiagnosticEvents);
        }
        /// <summary>
        /// Initializes a new instance of the
        /// <see cref="DataLoaderBase{TKey, TValue}"/> class.
        /// </summary>
        /// <param name="options">
        /// A configuration for <c>DataLoaders</c>.
        /// </param>
        /// <param name="cache">
        /// A cache instance for <c>Tasks</c>.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Throws if <paramref name="options"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Throws if <paramref name="cache"/> is <c>null</c>.
        /// </exception>
        protected DataLoaderBase(DataLoaderOptions <TKey> options, ITaskCache <TValue> cache)
        {
            _options = options ??
                       throw new ArgumentNullException(nameof(options));
            _buffer           = new TaskCompletionBuffer <TKey, TValue>();
            _cache            = cache ?? throw new ArgumentNullException(nameof(cache));
            _cacheKeyResolver = _options.CacheKeyResolver ??
                                ((TKey key) => key);

            StartAsyncBackgroundDispatching();
        }
Beispiel #16
0
        public void ConstructorBFetchNull()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = null;
            var options = new DataLoaderOptions <string>();

            // act
            Action verify = () => new DataLoader <string, string>(options,
                                                                  fetch);

            // assert
            Assert.Throws <ArgumentNullException>("fetch", verify);
        }
        public void DispatchAsyncNoException()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = TestHelpers
                                                       .CreateFetch <string, string>();
            var options = new DataLoaderOptions <string>();
            var loader  = new DataLoader <string, string>(options, fetch);

            // act
            Action verify = () => loader.DispatchAsync();

            // assert
            Assert.Null(Record.Exception(verify));
        }
        public void LoadCollectionNoException()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = TestHelpers
                                                       .CreateFetch <string, string>("Bar");
            var options = new DataLoaderOptions <string>();
            var loader  = new DataLoader <string, string>(options, fetch);

            // act
            Action verify = () => loader.LoadAsync(new List <string>());

            // assert
            Assert.Null(Record.Exception(verify));
        }
        public void SetNoException()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = TestHelpers
                                                       .CreateFetch <string, string>();
            var    options = new DataLoaderOptions <string>();
            var    loader  = new DataLoader <string, string>(options, fetch);
            var    key     = "Foo";
            string value   = null;

            // act
            Action verify = () => loader.Set(key, value);

            // assert
            Assert.Null(Record.Exception(verify));
        }
        public void SetKeyNull()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = TestHelpers
                                                       .CreateFetch <string, string>();
            var    options = new DataLoaderOptions <string>();
            var    loader  = new DataLoader <string, string>(options, fetch);
            string key     = null;
            var    value   = "Bar";

            // act
            Action verify = () => loader.Set(key, value);

            // assert
            Assert.Throws <ArgumentNullException>("key", verify);
        }
Beispiel #21
0
        public void ConstructorBOptionsNull()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = async keys =>
                                                       await Task.FromResult(new IResult <string> [0])
                                                       .ConfigureAwait(false);

            DataLoaderOptions <string> options = null;

            // act
            Action verify = () => new DataLoader <string, string>(options,
                                                                  fetch);

            // assert
            Assert.Throws <ArgumentNullException>("options", verify);
        }
Beispiel #22
0
        public void ClearNoException()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = async keys =>
                                                       await Task.FromResult(new IResult <string> [0])
                                                       .ConfigureAwait(false);

            var options = new DataLoaderOptions <string>();
            var loader  = new DataLoader <string, string>(options, fetch);

            // act
            Action verify = () => loader.Clear();

            // assert
            Assert.Null(Record.Exception(verify));
        }
Beispiel #23
0
        public void ConstructorEmpty()
        {
            // act
            var options = new DataLoaderOptions <string>();

            // assert
            Assert.False(options.AutoDispatching);
            Assert.True(options.Batching);
            Assert.Equal(TimeSpan.FromMilliseconds(50),
                         options.BatchRequestDelay);
            Assert.Null(options.CacheKeyResolver);
            Assert.Equal(1000, options.CacheSize);
            Assert.True(options.Caching);
            Assert.Equal(0, options.MaxBatchSize);
            Assert.Equal(TimeSpan.Zero, options.SlidingExpiration);
        }
        public async Task ExecuteBatchRequest()
        {
            var listener = new DispatchingListener();
            var observer = new DispatchingObserver(listener);

            using (DiagnosticListener.AllListeners.Subscribe(observer))
            {
                // arrange
                FetchDataDelegate <string, string> fetch = async keys =>
                {
                    var error = new Exception("Quux");

                    return(await Task.FromResult(new[]
                    {
                        Result <string> .Reject(error)
                    }).ConfigureAwait(false));
                };
                var options = new DataLoaderOptions <string>();
                var loader  = new DataLoader <string, string>(options, fetch);

                // act
                try
                {
                    await loader.LoadAsync("Foo").ConfigureAwait(false);
                }
                catch
                {
                }

                // assert
                Assert.Collection(listener.Keys,
                                  (key) => Assert.Equal("Foo", key));
                Assert.Collection(listener.Values,
                                  (item) =>
                {
                    Assert.Equal("Foo", item.Key);
                    Assert.True(item.Value.IsError);
                    Assert.Equal("Quux", item.Value.Error.Message);
                });
                Assert.Collection(listener.Errors,
                                  (item) =>
                {
                    Assert.Equal("Foo", item.Key);
                    Assert.Equal("Quux", item.Value.Message);
                });
            }
        }
        public void IDataLoaderLoadSingleNoException()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = TestHelpers
                                                       .CreateFetch <string, string>("Bar");
            var         options = new DataLoaderOptions <string>();
            IDataLoader loader  = new DataLoader <string, string>(
                options,
                fetch);
            var key = "Foo";

            // act
            Action verify = () => loader.LoadAsync(key);

            // assert
            Assert.Null(Record.Exception(verify));
        }
Beispiel #26
0
        public async Task DispatchAsyncNoException()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = async keys =>
                                                       await Task.FromResult(new IResult <string> [0])
                                                       .ConfigureAwait(false);

            var options = new DataLoaderOptions <string>();
            var loader  = new DataLoader <string, string>(options, fetch);

            // act
            Func <Task> verify = () => loader.DispatchAsync();

            // assert
            Assert.Null(await Record.ExceptionAsync(verify)
                        .ConfigureAwait(false));
        }
        public void ConstructorAllProps1()
        {
            // act
            var options = new DataLoaderOptions
            {
                Cache            = new TaskCache(1),
                Caching          = true,
                MaxBatchSize     = 1,
                DiagnosticEvents = new DataLoaderDiagnosticEventListener()
            };

            // assert
            Assert.NotNull(options.Cache);
            Assert.True(options.Caching);
            Assert.Equal(1, options.MaxBatchSize);
            Assert.NotNull(options.DiagnosticEvents);
        }
        public void ConstructorAllProps2()
        {
            // act
            var options = new DataLoaderOptions
            {
                Cache            = null,
                Caching          = false,
                MaxBatchSize     = 10,
                DiagnosticEvents = null
            };

            // assert
            Assert.Null(options.Cache);
            Assert.False(options.Caching);
            Assert.Equal(10, options.MaxBatchSize);
            Assert.Null(options.DiagnosticEvents);
        }
        public async Task SetNewCacheEntry()
        {
            // arrange
            FetchDataDelegate <string, string> fetch = TestHelpers
                                                       .CreateFetch <string, string>();
            var options = new DataLoaderOptions <string>();
            var loader  = new DataLoader <string, string>(options, fetch);
            var key     = "Foo";
            var value   = "Bar";

            // act
            loader.Set(key, value);

            // assert
            var loadResult = await loader.LoadAsync(key).ConfigureAwait(false);

            Assert.Equal(value, loadResult);
        }
Beispiel #30
0
        public void ConstructorAllProps()
        {
            // act
            var options = new DataLoaderOptions <string>
            {
                Batch            = false,
                Cache            = new TaskCache(1),
                CacheKeyResolver = k => k,
                CacheSize        = 1,
                Caching          = false,
                MaxBatchSize     = 1
            };

            // assert
            options.MatchSnapshot(matchOptions => matchOptions
                                  .Assert(fieldOption =>
                                          Assert.NotNull(fieldOption.Field <object>("CacheKeyResolver"))));
        }