Ejemplo n.º 1
0
 private SemaphoreSlim GetOrCreateLock(
     string key,
     DistributedCacheEntryOptions?distributedCacheEntryOptions)
 {
     KeySemaphore.Wait();
     try
     {
         return(L1Cache.GetOrCreate(
                    $"{L1L2RedisCacheOptions.LockKeyPrefix}{key}",
                    cacheEntry =>
         {
             cacheEntry.AbsoluteExpiration =
                 distributedCacheEntryOptions?.AbsoluteExpiration;
             cacheEntry.AbsoluteExpirationRelativeToNow =
                 distributedCacheEntryOptions?.AbsoluteExpirationRelativeToNow;
             cacheEntry.SlidingExpiration =
                 distributedCacheEntryOptions?.SlidingExpiration;
             return new SemaphoreSlim(1, 1);
         }) ??
                new SemaphoreSlim(1, 1));
     }
     finally
     {
         KeySemaphore.Release();
     }
 }
Ejemplo n.º 2
0
    private async Task <SemaphoreSlim> GetOrCreateLockAsync(
        string key,
        DistributedCacheEntryOptions?distributedCacheEntryOptions,
        CancellationToken cancellationToken = default)
    {
        await KeySemaphore.WaitAsync(cancellationToken);

        try
        {
            return(await L1Cache.GetOrCreateAsync(
                       $"{L1L2RedisCacheOptions.LockKeyPrefix}{key}",
                       cacheEntry =>
            {
                cacheEntry.AbsoluteExpiration =
                    distributedCacheEntryOptions?.AbsoluteExpiration;
                cacheEntry.AbsoluteExpirationRelativeToNow =
                    distributedCacheEntryOptions?.AbsoluteExpirationRelativeToNow;
                cacheEntry.SlidingExpiration =
                    distributedCacheEntryOptions?.SlidingExpiration;
                return Task.FromResult(new SemaphoreSlim(1, 1));
            }) ??
                   new SemaphoreSlim(1, 1));
        }
        finally
        {
            KeySemaphore.Release();
        }
    }
        public void SemaphoreWithKeyDecorator_SingleConcurrency_KeySemaphore_No_KeySelector_Tests()
        {
            var keySemaphore = new KeySemaphore <string>(1, StringComparer.OrdinalIgnoreCase);

            Assert.Throws <KeySelectorMissingException>(
                () =>
            {
                Create.SimpleFunc <string>(b => b.FireAndForget().Semaphore(c => c.KeySemaphore(keySemaphore)).Handler(async m => { await Task.Delay(500); }));
            });
        }
        public async Task SemaphoreWithKeyDecorator_SingleConcurrency_KeySemaphore_Tests()
        {
            var count = 0;

            var keySemaphore = new KeySemaphore <string>(1, StringComparer.OrdinalIgnoreCase);

            var func = Create.SimpleFunc <string>(
                b => b
                .FireAndForget()
                .Semaphore(c => c.KeySemaphore(keySemaphore).KeySelector(m => m))
                .Handler(
                    async m =>
            {
                await Task.Delay(500);
                Interlocked.Increment(ref count);
            }));

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            func("A");
            func("a");
            func("a");
            func("a");
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed

            await Task.Delay(200);

            Assert.Equal(0, count);

            await Task.Delay(600);

            Assert.Equal(1, count);

            await Task.Delay(500);

            Assert.Equal(2, count);
        }
        /// <summary>
        ///     Sets the key semaphore
        /// </summary>
        /// <typeparam name="TKeyType">The key types</typeparam>
        /// <param name="keySemaphore">A key semaphore</param>
        /// <returns>A SemaphoreWithKeyDecoratorBuilder</returns>
        public SemaphoreWithKeyDecoratorBuilder <TMessageType, TKeyType> KeySemaphore <TKeyType>(KeySemaphore <TKeyType> keySemaphore)
        {
            var newBuilder = new SemaphoreWithKeyDecoratorBuilder <TMessageType, TKeyType>().MaxNumberOfConcurrentMessages(this.maxNumberOfConcurrentMessages)
                             .KeySemaphore(keySemaphore);

            this.buildFunc = newBuilder.Build;
            return(newBuilder);
        }