Documentation suggests using IDistributedLockProvider instead of IAbpDistributedLock (https://docs.abp.io/en/abp/latest/Distributed-Locking)
Btw, is IAbpDistributedLock really distributed or in-process? Because we are in a real distributed environment and need a real distributed lock.
I can't reproduce the problem, can you try the following code?
context.Services.AddSingleton<IDistributedLockProvider>(sp => { var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); return new RedisDistributedSynchronizationProvider(connection.GetDatabase()); });
app.Use(async (httpContext, next) => { await using (var handler = await httpContext.RequestServices.GetRequiredService<IAbpDistributedLock>().TryAcquireAsync("AbpBackgroundJobWorker", TimeSpan.FromSeconds(10))) { httpContext.Response.StatusCode = 200; return; } await next(httpContext); });
The second code block produces error like below:
When I change it like this, the problem is not solved:
app.Use(async (httpContext, next) => { await using (var handler = await httpContext.RequestServices.GetRequiredService() .TryAcquireAsync("AbpBackgroundJobWorker", TimeSpan.FromSeconds(10))) { httpContext.Response.StatusCode = 200; await next(httpContext); } });
Btw, we do not use IAbpDistributedLock but the IDistributedLockProvider interface for distributed lock.
public class MyBackgroundJob : AsyncBackgroundJob<MyRequest>, ITransientDependency
{
private readonly IMyDomainService _myDomainService;
private readonly IDistributedLockProvider _distributedLockProvider;
public MyBackgroundJob(IMyDomainService myDomainService,
IDistributedLockProvider distributedLockProvider)
{
_myDomainService = myDomainService;
_distributedLockProvider = distributedLockProvider;
}
public override async Task ExecuteAsync(MyRequest args)
{
var distributedLock = _distributedLockProvider.CreateLock(MyConsts.MyBackgroundJobName);
await using (var handle = await distributedLock.TryAcquireAsync())
{
if (handle != null)
{
await _myDomainService.MyMethod(args);
}
}
}
}
hi
If the problem cannot be reproduced every time, you can observe it for a while.
Hi maliming,
Problem is being reproduced every time.
Hi @gterdem, thank you for your feedback. But I think this is not a good solution in a production scenario or in a pipeline. (Since these command-line tools may not be available in some environments, and this is the most significant benefit of DbMigrator - a standard console application to do migrations)
And if I would need to execute these ef commands manually in some scenarios, this situation seriously reduces the benefit/usefulness of DbMigrator application. As you may guess reverting a migration is almost always a requirement.
So I think, it would be great if DbMigrator have some parameter <migration-name> and made the same reverting. Is there any roadmap to support such functionality?
Thank you for your help maliming.
By the way, as we are an Enterprise License customer, I have also sent an email to the volosoft contact email address about the issue. (But didn't have a response yet) If we communicate over there maybe I can give more info as it will not be public.
As this is a commercial project, I would rather not share the project structure. But I can give detail about what you are trying to learn.
In addition, when I try to access the feature (using IFeatureChecker) in a plain controller or app service method it works.
Hi Maliming,
I am trying to access it inside a background hosted service project and inside a QuartzBackgroundWorkerBase derived class. (This is some background project for scheduled tasks.)
Btw, as I look at the source code, both IFeatureChecker and IFeatureManager uses line:
var featureDefinition = FeatureDefinitionManager.Get(name);
and I think this line throws the "Undefined feature" exception. But I don't know why.
public virtual FeatureDefinition Get(string name)
{
Check.NotNull(name, nameof(name));
var feature = GetOrNull(name);
if (feature == null)
{
throw new AbpException("Undefined feature: " + name);
}
return feature;
}
Thank you