Example #1
0
        internal async Task CreateAsync(UrlItem urlItem)
        {
            // Add item to database
            _dbContext.Urls.Add(urlItem);

            var       success       = false;
            Exception?lastException = null;
            // Try max 10 times before giving up
            string key = null;

            for (var i = 0; i < 10; i++)
            {
                //  Create random id
                key = Helpers.GetRandomKey(_config.Url);

                // Try to add item to database
                urlItem.Key = key;
                try
                {
                    await _dbContext.SaveChangesAsync();

                    success = true;
                }
                catch (DbUpdateException dbUpdateException) when((dbUpdateException.InnerException as SqlException)?.Number == 2601)
                {
                    // Already exists: We need to retry
                    _logger.LogInformation(dbUpdateException, $"Collision creating ShortUrl: {urlItem.Key}");
                    lastException = dbUpdateException;
                    continue;
                }
                catch (Exception exception)
                {
                    // Not sure what is wrong, log it and try again
                    _logger.LogError(exception, $"Creating new ShortUrl: {JsonSerializer.Serialize(urlItem)}");
                    lastException = exception;
                    continue;
                }
            }

            // Not success: Throw last error
            if (!success)
            {
                throw lastException !;
            }

            // Success: Add item to recent used cache since it will probably be used immediately
            var cacheEntryOptions = new MemoryCacheEntryOptions();

            cacheEntryOptions.Size = 1;
            _cache.Set <UrlItem>(key, urlItem, cacheEntryOptions);
        }
Example #2
0
 internal Task Save()
 {
     return(ShortUrlDbContext.SaveChangesAsync());
 }