Finbuckle.MultiTenant icon indicating copy to clipboard operation
Finbuckle.MultiTenant copied to clipboard

Using Multitenant inside a Hangfire batch

Open auri179 opened this issue 2 years ago • 4 comments

Hello,

We have an issue using multitenant inside Hangfire batch. We are using multitenant in header strategy and when we are in controllers everything is fine. But for some reasons we have to bulk edit some entities asynchronously, for that we are using Hangfire jobs. The entity to update is a multitenant entity and inside hangfire job the HttpContext is not valued because we are not in a HttpRequest... All the time the DbContext is raising an exception "MultiTenant Entity cannot be changed if TenantInfo is null.". We are only in update mode and we d'ont have to update the tenant because we are tenant scoped.

  • On the entity the property tenantInfo cannot be changed manually
  • We can't ignore the field during the update

What can we do to achieve this ?

Thanks

auri179 avatar Oct 27 '21 08:10 auri179

Hi I'm not familiar with Hangfire jobs, but I think I can see what is happening. The DbContext(s) are being spun up with a null TenantInfo object. In normal cases it tries to protect from changes like this but I understand your situation it would make sense to allow bulk updates for efficiency. I was about to point you toward TenantNotSetMode but I see we don't have an option there that would help you. I think I add an Ignore option there to the ToDo list, but for now unfortunately it won't work.

Is it possible that you can break up your bulk edit into bulk edit by tenant and for each one spin up a dbcontext with a TenantInfo object containing the correct TenantId?

AndrewTriesToCode avatar Oct 28 '21 01:10 AndrewTriesToCode

I've kind of the same problem.

As I could research about this, TenantInfo is stored over HttpContext but HangFire doesn't use HttpContext... :(.

Any alternative to store TenantInfo in some other place?

For now I solved this doing HangFire make a HTTP request back to my API, but I think this is not optimal ... API -> HangFire -> API

SkualoSpA avatar Nov 02 '21 16:11 SkualoSpA

Hi, TenantInfo isn't really stored in HttpContext, but rather in a global IMultiTenantAccessor<T> instance which uses an AsyncLocal<MultiTenantContext<T>> to store the current multitenant context. Do you have access to DI where the code is needed? You might be able to inject IMultiTenantContextAccessor<T> and use it to get to the tenant info.

AndrewTriesToCode avatar Nov 02 '21 23:11 AndrewTriesToCode

I'm assuming this happens because the background job is using something that has a dependency on a EFCoreStoreDbContext data context?

If so, can the job be rewritten to remove that dependency, since it sounds like what you're doing isn't really tenant-specific?

For my Hangfire jobs, I try to make them as atomic as possible - this allows me to enqueue them in a few different contexts (within ASP.NET Core and within TopShelf-enabled background services, for example) without adding a lot of transitive dependencies.

(Sorry, wasn't paying attention to the issue date - this was probably resolved a while ago)

tiesont avatar Aug 13 '22 21:08 tiesont