예제 #1
0
        public async Task AcquireLockAsyncTest()
        {
            var cacheClient = new InMemoryCacheClient(new ProtobufSerializer());
            var tokenSource = new CancellationTokenSource();

            var testLock = await cacheClient.AcquireLockAsync("test:InMemory:acquire", tokenSource.Token);

            Assert.Equal(1, await cacheClient.GetAsync <int>("test:InMemory:acquire"));

            await testLock.ReleaseAsync();

            Assert.Null(await cacheClient.GetAsync <string>("test:InMemory:acquire"));
        }
예제 #2
0
        public async Task <GeoResult> ResolveIpAsync(string ip, CancellationToken cancellationToken = new CancellationToken())
        {
            if (String.IsNullOrEmpty(ip) || (!ip.Contains(".") && !ip.Contains(":")))
            {
                return(null);
            }

            ip = ip.Trim();
            if (ip.IsPrivateNetwork())
            {
                return(null);
            }

            var cacheValue = await _localCache.GetAsync <GeoResult>(ip).AnyContext();

            if (cacheValue.HasValue)
            {
                return(cacheValue.Value);
            }

            GeoResult result   = null;
            var       database = await GetDatabaseAsync(cancellationToken).AnyContext();

            if (database == null)
            {
                return(null);
            }

            try {
                if (database.TryCity(ip, out var city) && city?.Location != null)
                {
                    result = new GeoResult {
                        Latitude  = city.Location.Latitude,
                        Longitude = city.Location.Longitude,
                        Country   = city.Country.IsoCode,
                        Level1    = city.MostSpecificSubdivision.IsoCode,
                        Locality  = city.City.Name
                    };
                }

                await _localCache.SetAsync(ip, result).AnyContext();

                return(result);
            } catch (Exception ex) {
                if (ex is GeoIP2Exception)
                {
                    if (_logger.IsEnabled(LogLevel.Trace))
                    {
                        _logger.LogTrace(ex, ex.Message);
                    }
                    await _localCache.SetAsync <GeoResult>(ip, null).AnyContext();
                }
                else if (_logger.IsEnabled(LogLevel.Error))
                {
                    _logger.LogError(ex, "Unable to resolve geo location for ip: {IP}", ip);
                }

                return(null);
            }
        }
예제 #3
0
        public async Task <GeoResult> ResolveIpAsync(string ip, CancellationToken cancellationToken = new CancellationToken())
        {
            if (String.IsNullOrWhiteSpace(ip) || (!ip.Contains(".") && !ip.Contains(":")))
            {
                return(null);
            }

            ip = ip.Trim();

            var cacheValue = await _localCache.GetAsync <GeoResult>(ip).AnyContext();

            if (cacheValue.HasValue)
            {
                return(cacheValue.Value);
            }

            GeoResult result = null;

            if (ip.IsPrivateNetwork())
            {
                return(null);
            }

            var database = await GetDatabaseAsync(cancellationToken).AnyContext();

            if (database == null)
            {
                return(null);
            }

            try {
                var city = database.City(ip);
                if (city?.Location != null)
                {
                    result = new GeoResult {
                        Latitude  = city.Location.Latitude,
                        Longitude = city.Location.Longitude,
                        Country   = city.Country.IsoCode,
                        Level1    = city.MostSpecificSubdivision.IsoCode,
                        Locality  = city.City.Name
                    };
                }

                await _localCache.SetAsync(ip, result).AnyContext();

                return(result);
            } catch (Exception ex) {
                if (ex is AddressNotFoundException || ex is GeoIP2Exception)
                {
                    Logger.Trace().Message(ex.Message).Write();
                    await _localCache.SetAsync <GeoResult>(ip, null).AnyContext();
                }
                else
                {
                    Logger.Error().Exception(ex).Message("Unable to resolve geo location for ip: " + ip).Write();
                }

                return(null);
            }
        }
예제 #4
0
        public async Task <ClientInfo> ParseAsync(string userAgent)
        {
            if (String.IsNullOrEmpty(userAgent))
            {
                return(null);
            }

            var cacheValue = await _localCache.GetAsync <ClientInfo>(userAgent).AnyContext();

            if (cacheValue.HasValue)
            {
                return(cacheValue.Value);
            }

            ClientInfo info = null;

            try {
                info = _parser.Value.Parse(userAgent);
            } catch (Exception ex) {
                _logger.LogWarning("Unable to parse user agent {UserAgent}. Exception: {Message}", userAgent, ex.Message);
            }

            await _localCache.SetAsync(userAgent, info).AnyContext();

            return(info);
        }
예제 #5
0
        public async Task <ClientInfo> ParseAsync(string userAgent, string projectId = null)
        {
            if (String.IsNullOrEmpty(userAgent))
            {
                return(null);
            }

            var cacheValue = await _cache.GetAsync <ClientInfo>(userAgent).AnyContext();

            if (cacheValue.HasValue)
            {
                return(cacheValue.Value);
            }

            ClientInfo info = null;

            try {
                info = _parser.Value.Parse(userAgent);
            } catch (Exception ex) {
                Logger.Warn().Project(projectId).Message($"Unable to parse user agent {userAgent}. Exception: {ex.Message}").Write();
            }

            await _cache.SetAsync(userAgent, info).AnyContext();

            return(info);
        }
예제 #6
0
        protected virtual async Task OnCompletedAsync(string id)
        {
            var queueEntry = await _queueEntryCache.GetAsync <QueueEntryMetadata>(id).AnyContext();

            if (queueEntry.HasValue && queueEntry.Value.DequeuedTimeUtc > DateTime.MinValue)
            {
                queueEntry.Value.ProcessingTime = DateTime.UtcNow.Subtract(queueEntry.Value.DequeuedTimeUtc);
            }

            await(Completed?.InvokeAsync(this, new CompletedEventArgs <T> {
                Queue    = this,
                Metadata = queueEntry.Value
            }) ?? TaskHelper.Completed()).AnyContext();

            await _queueEntryCache.RemoveAsync(id).AnyContext();
        }
예제 #7
0
        private async Task <CacheValue <string> > GetCache(string cachekey, string cachevalue)
        {
            ICacheClient cache = new InMemoryCacheClient();
            await cache.SetAsync(cachekey, cachevalue);

            return(await cache.GetAsync <string>(cachekey));
        }
예제 #8
0
        public async Task <SemanticVersion> ParseAsync(string version)
        {
            version = version?.Trim();
            if (String.IsNullOrEmpty(version))
            {
                return(null);
            }

            var cacheValue = await _localCache.GetAsync <SemanticVersion>(version).AnyContext();

            if (cacheValue.HasValue)
            {
                return(cacheValue.Value);
            }

            int spaceIndex = version.IndexOf(" ", StringComparison.OrdinalIgnoreCase);

            if (spaceIndex > 0)
            {
                version = version.Substring(0, spaceIndex).Trim();
            }

            int wildCardIndex = version.IndexOf("*", StringComparison.OrdinalIgnoreCase);

            if (wildCardIndex > 0)
            {
                version = version.Replace(".*", String.Empty).Replace("*", String.Empty);
            }

            SemanticVersion semanticVersion = null;

            if (version.Length >= 5 && SemanticVersion.TryParse(version, out semanticVersion))
            {
                await _localCache.SetAsync(version, semanticVersion).AnyContext();

                return(semanticVersion);
            }

            Version v;
            int     major;

            if (version.Length >= 3 && Version.TryParse(version, out v))
            {
                semanticVersion = new SemanticVersion(v.Major > 0 ? v.Major : 0, v.Minor > 0 ? v.Minor : 0, v.Build > 0 ? v.Build : 0, v.Revision >= 0 ? new[] { v.Revision.ToString() } : Enumerable.Empty <string>());
            }
            else if (Int32.TryParse(version, out major))
            {
                semanticVersion = new SemanticVersion(major, 0);
            }
            else
            {
                _logger.Info("Unable to parse version: {version}", version);
            }

            await _localCache.SetAsync(version, semanticVersion).AnyContext();

            return(semanticVersion);
        }
        public async Task <Location> ResolveIpAsync(string ip, CancellationToken cancellationToken = new CancellationToken())
        {
            if (String.IsNullOrWhiteSpace(ip) || (!ip.Contains(".") && !ip.Contains(":")))
            {
                return(null);
            }

            ip = ip.Trim();

            var cacheValue = await _cache.GetAsync <Location>(ip).AnyContext();

            if (cacheValue.HasValue)
            {
                return(cacheValue.Value);
            }

            Location location = null;

            if (ip.IsPrivateNetwork())
            {
                return(null);
            }

            var database = await GetDatabaseAsync(cancellationToken).AnyContext();

            if (database == null)
            {
                return(null);
            }

            try {
                var city = database.City(ip);
                if (city?.Location != null)
                {
                    location = new Location {
                        Latitude = city.Location.Latitude, Longitude = city.Location.Longitude
                    }
                }
                ;

                await _cache.SetAsync(ip, location).AnyContext();

                return(location);
            } catch (Exception ex) {
                if (ex is AddressNotFoundException || ex is GeoIP2Exception)
                {
                    Logger.Trace().Message(ex.Message).Write();
                    await _cache.SetAsync <Location>(ip, null).AnyContext();
                }
                else
                {
                    Logger.Error().Exception(ex).Message("Unable to resolve geo location for ip: " + ip).Write();
                }

                return(null);
            }
        }
예제 #10
0
        public async Task CanSetMaxItems()
        {
            Log.MinimumLevel = LogLevel.Trace;

            // run in tight loop so that the code is warmed up and we can catch timing issues
            for (int x = 0; x < 5; x++)
            {
                var cache = new InMemoryCacheClient(o => o.MaxItems(10).CloneValues(true));

                using (cache) {
                    await cache.RemoveAllAsync();

                    for (int i = 0; i < cache.MaxItems; i++)
                    {
                        await cache.SetAsync("test" + i, i);
                    }

                    _logger.LogTrace(String.Join(",", cache.Keys));
                    Assert.Equal(10, cache.Count);
                    await cache.SetAsync("next", 1);

                    _logger.LogTrace(String.Join(",", cache.Keys));
                    Assert.Equal(10, cache.Count);
                    Assert.False((await cache.GetAsync <int>("test0")).HasValue);
                    Assert.Equal(1, cache.Misses);
                    await SystemClock.SleepAsync(50); // keep the last access ticks from being the same for all items

                    Assert.NotNull(await cache.GetAsync <int?>("test1"));
                    Assert.Equal(1, cache.Hits);
                    await cache.SetAsync("next2", 2);

                    _logger.LogTrace(String.Join(",", cache.Keys));
                    Assert.False((await cache.GetAsync <int>("test2")).HasValue);
                    Assert.Equal(2, cache.Misses);
                    Assert.True((await cache.GetAsync <int>("test1")).HasValue);
                    Assert.Equal(2, cache.Misses);
                }
            }
        }
예제 #11
0
        public async Task AcquireLockAsyncTwiceThrowsTimeoutTest()
        {
            var cacheClient = new InMemoryCacheClient(new ProtobufSerializer());
            var tokenSource = new CancellationTokenSource();

            var testLock = await cacheClient.AcquireLockAsync(
                "test:acquire:multiple", tokenSource.Token);

            tokenSource.CancelAfter(1000);
            await Assert.ThrowsAnyAsync <OperationCanceledException>(
                () => cacheClient.AcquireLockAsync(
                    "test:acquire:multiple", tokenSource.Token)
                .AsTask());

            await testLock.ReleaseAsync();

            Assert.Null(await cacheClient.GetAsync <string>("test:acquire:multiple"));
        }
예제 #12
0
        private async Task <GeoResult> GetGeoFromIpAddressesAsync(IEnumerable <string> ips)
        {
            foreach (var ip in ips)
            {
                if (String.IsNullOrEmpty(ip))
                {
                    continue;
                }

                var cacheValue = await _localCache.GetAsync <GeoResult>(ip).AnyContext();

                if (cacheValue.HasValue && cacheValue.IsNull)
                {
                    continue;
                }

                if (cacheValue.HasValue)
                {
                    return(cacheValue.Value);
                }

                var result = await _geoIpService.ResolveIpAsync(ip).AnyContext();

                if (result == null || !result.IsValid())
                {
                    await _localCache.SetAsync <GeoResult>(ip, null).AnyContext();

                    continue;
                }

                await _localCache.SetAsync(ip, result).AnyContext();

                return(result);
            }

            return(null);
        }
        public async Task CanIncrementUsageAsync()
        {
            var messageBus = GetService <IMessageBus>();

            var countdown = new AsyncCountdownEvent(2);

            messageBus.Subscribe <PlanOverage>(po => {
                _logger.Info($"Plan Overage for {po.OrganizationId} (Hourly: {po.IsHourly})");
                countdown.Signal();
            });

            var o = await _repository.AddAsync(new Organization { Name = "Test", MaxEventsPerMonth = 750, PlanId = BillingManager.FreePlan.Id });

            await _configuration.Client.RefreshAsync();

            Assert.InRange(o.GetHourlyEventLimit(), 1, 750);

            int totalToIncrement = o.GetHourlyEventLimit() - 1;

            Assert.False(await _repository.IncrementUsageAsync(o.Id, false, totalToIncrement));
            await _configuration.Client.RefreshAsync();

            o = await _repository.GetByIdAsync(o.Id);

            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(2, countdown.CurrentCount);
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(0, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(0, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));

            Assert.True(await _repository.IncrementUsageAsync(o.Id, false, 2));
            await _configuration.Client.RefreshAsync();

            o = await _repository.GetByIdAsync(o.Id);

            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(1, countdown.CurrentCount);
            Assert.Equal(totalToIncrement + 2, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement + 2, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(1, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(1, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));

            o = await _repository.AddAsync(new Organization { Name = "Test", MaxEventsPerMonth = 750, PlanId = BillingManager.FreePlan.Id });

            await _configuration.Client.RefreshAsync();

            totalToIncrement = o.GetHourlyEventLimit() + 20;
            Assert.True(await _repository.IncrementUsageAsync(o.Id, false, totalToIncrement));

            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(0, countdown.CurrentCount);
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(20, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(20, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));
        }