public async Task Run(CancellationToken cancellationToken) { var directoryInfo = ArticleExtractorJob.GetDirectory(); var lck = new FileDistributedLock(directoryInfo, "extract-recommendations"); using (var distributedLock = await lck.TryAcquireAsync()) { if (distributedLock == null) { return; } var popularArticles = await GetPopularArticles(cancellationToken); var result = GetSimilarArticlesByWord2Vec(popularArticles).ToList(); foreach (var articles in result) { var firstArticle = articles.First(); var recommendation = RecommendationAggregate.Create(firstArticle.UserId); foreach (var article in articles) { recommendation.Recommend(article.ArticleId, article.Score); } await _recommendationCommandRepository.Add(recommendation, cancellationToken); await _recommendationCommandRepository.SaveChanges(cancellationToken); } } }
public async Task Run(CancellationToken cancellationToken) { var directoryInfo = GetDirectory(); var lck = new FileDistributedLock(directoryInfo, "extract-articles"); using (var distributedLock = await lck.TryAcquireAsync()) { if (distributedLock == null) { return; } var datasources = await _datasourceCommandRepository.GetAll(cancellationToken); foreach (var datasource in datasources) { try { await ExtractArticlesFromFeed(datasource, cancellationToken); } catch (Exception ex) { _logger.LogError(ex.ToString()); } } await _datasourceCommandRepository.Update(datasources, cancellationToken); await _datasourceCommandRepository.SaveChanges(cancellationToken); } }
public void TestThrowsUnauthorizedAccessExceptionInCaseOfDirectoryPermissionViolation() { var @lock = new FileDistributedLock(new DirectoryInfo(@"C:\Windows\MedallionDistributedLock"), Guid.NewGuid().ToString()); var exception = Assert.Throws <InvalidOperationException>(() => @lock.TryAcquire()?.Dispose()); Assert.IsInstanceOf <UnauthorizedAccessException>(exception.InnerException); Assert.IsFalse(Directory.Exists(Path.GetDirectoryName(@lock.Name))); }
public async Task Consume(ConsumeContext <ArticleAddedEvent> context) { var directoryInfo = ArticleExtractorJob.GetDirectory(); var lck = new FileDistributedLock(directoryInfo, "article-added"); using (var distributedLock = await lck.TryAcquireAsync()) { if (distributedLock == null) { var random = new Random(); Thread.Sleep(random.Next(100, 2000)); return; } var datasource = await _dataSourceCommandRepository.Get(context.Message.DataSourceId, CancellationToken.None); datasource.AddArticle(context.Message.PublishDate); await _dataSourceCommandRepository.Update(new[] { datasource }, CancellationToken.None); await _dataSourceCommandRepository.SaveChanges(CancellationToken.None); } }
public void TestThrowsUnauthorizedAccessExceptionInCaseOfFilePermissionViolation() { var @lock = new FileDistributedLock(new DirectoryInfo(@"C:\Windows"), Guid.NewGuid().ToString()); Assert.Throws <UnauthorizedAccessException>(() => @lock.TryAcquire()?.Dispose()); }
public static int Main(string[] args) { var type = args[0]; var name = args[1]; IDisposable?handle; switch (type) { case nameof(SqlDistributedLock): handle = new SqlDistributedLock(name, SqlServerCredentials.ConnectionString).Acquire(); break; case "Write" + nameof(SqlDistributedReaderWriterLock): handle = new SqlDistributedReaderWriterLock(name, SqlServerCredentials.ConnectionString).AcquireWriteLock(); break; case nameof(SqlDistributedSemaphore) + "1AsMutex": handle = new SqlDistributedSemaphore(name, maxCount: 1, connectionString: SqlServerCredentials.ConnectionString).Acquire(); break; case nameof(SqlDistributedSemaphore) + "5AsMutex": handle = new SqlDistributedSemaphore(name, maxCount: 5, connectionString: SqlServerCredentials.ConnectionString).Acquire(); break; case nameof(PostgresDistributedLock): handle = new PostgresDistributedLock(new PostgresAdvisoryLockKey(name), PostgresCredentials.GetConnectionString(Environment.CurrentDirectory)).Acquire(); break; case "Write" + nameof(PostgresDistributedReaderWriterLock): handle = new PostgresDistributedReaderWriterLock(new PostgresAdvisoryLockKey(name), PostgresCredentials.GetConnectionString(Environment.CurrentDirectory)).AcquireWriteLock(); break; case nameof(EventWaitHandleDistributedLock): handle = new EventWaitHandleDistributedLock(name).Acquire(); break; case nameof(WaitHandleDistributedSemaphore) + "1AsMutex": handle = new WaitHandleDistributedSemaphore(name, maxCount: 1).Acquire(); break; case nameof(WaitHandleDistributedSemaphore) + "5AsMutex": handle = new WaitHandleDistributedSemaphore(name, maxCount: 5).Acquire(); break; case nameof(AzureBlobLeaseDistributedLock): handle = new AzureBlobLeaseDistributedLock( new BlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, name), o => o.Duration(TimeSpan.FromSeconds(15)) ) .Acquire(); break; case nameof(FileDistributedLock): handle = new FileDistributedLock(new FileInfo(name)).Acquire(); break; case nameof(RedisDistributedLock) + "1": handle = AcquireRedisLock(name, serverCount: 1); break; case nameof(RedisDistributedLock) + "3": handle = AcquireRedisLock(name, serverCount: 3); break; case nameof(RedisDistributedLock) + "2x1": handle = AcquireRedisLock(name, serverCount: 2); // we know the last will fail; don't bother (we also don't know its port) break; case nameof(RedisDistributedLock) + "1WithPrefix": handle = AcquireRedisLock("distributed_locks:" + name, serverCount: 1); break; case "Write" + nameof(RedisDistributedReaderWriterLock) + "1": handle = AcquireRedisWriteLock(name, serverCount: 1); break; case "Write" + nameof(RedisDistributedReaderWriterLock) + "3": handle = AcquireRedisWriteLock(name, serverCount: 3); break; case "Write" + nameof(RedisDistributedReaderWriterLock) + "2x1": handle = AcquireRedisWriteLock(name, serverCount: 2); // we know the last will fail; don't bother (we also don't know its port) break; case "Write" + nameof(RedisDistributedReaderWriterLock) + "1WithPrefix": handle = AcquireRedisWriteLock("distributed_locks:" + name, serverCount: 1); break; case string _ when type.StartsWith(nameof(RedisDistributedSemaphore)): { var maxCount = type.EndsWith("1AsMutex") ? 1 : type.EndsWith("5AsMutex") ? 5 : throw new ArgumentException(type); handle = new RedisDistributedSemaphore( name, maxCount, GetRedisDatabases(serverCount: 1).Single(), // in order to see abandonment work in a reasonable timeframe, use very short expiry options => options.Expiry(TimeSpan.FromSeconds(1)) .BusyWaitSleepTime(TimeSpan.FromSeconds(.1), TimeSpan.FromSeconds(.3)) ).Acquire(); break; } default: Console.Error.WriteLine($"type: {type}"); return(123); } Console.WriteLine("Acquired"); Console.Out.Flush(); if (Console.ReadLine() != "abandon") { handle.Dispose(); } return(0); }