Using IContentService within a Hangfire task occas...
# help-with-umbraco
m
I have a hangfire task that loops through a bunch of data from an API, uses it to either Save, Save & Publish or Unpublish multiple content items. The ContentService itself seesm to be working as expected and is able to update each bit of content correctly, but I'm seeing the following error somewhat sporadically.
Copy code
prolog
[12:30:03 ERR] Error occurred executing workItem.
System.AggregateException: One or more errors occurred. (No AmbientContext was found.)
 ---> System.InvalidOperationException: No AmbientContext was found.
   at Umbraco.Cms.Infrastructure.Scoping.AmbientScopeContextStack.Pop()
   at Umbraco.Cms.Infrastructure.Scoping.ScopeProvider.PopAmbientScopeContext()
   at Umbraco.Cms.Infrastructure.Scoping.Scope.<>c__DisplayClass56_0.<RobustExit>g__HandleScopeContext|0()
   at Umbraco.Cms.Infrastructure.Scoping.Scope.TryFinally(Action[] actions)
   --- End of inner exception stack trace ---
   at Umbraco.Cms.Infrastructure.Scoping.Scope.TryFinally(Action[] actions)
   at Umbraco.Cms.Infrastructure.Scoping.Scope.RobustExit(Boolean completed, Boolean onException)
   at Umbraco.Cms.Infrastructure.Scoping.Scope.DisposeLastScope()
   at Umbraco.Cms.Infrastructure.Scoping.Scope.Dispose()
   at Umbraco.Cms.Infrastructure.Examine.ExamineUmbracoIndexingHandler.DeferredReIndexForContent.<>c__DisplayClass6_0.<Execute>b__0(CancellationToken cancellationToken)
   at Umbraco.Cms.Infrastructure.HostedServices.QueuedHostedService.BackgroundProcessing(CancellationToken stoppingToken)
This error seems to occur more frequently on the first run, then less so afterwards, although it does still happen. For context, it's currently updated around 20 content items.
I've read through the following articles and feeds and have implement multiple suggestions such as using a Background Scope and wrapping the save and publish logic with
using (ExecutionContext.SuppressFlow())
but nothing seems to do the job. - https://github.com/umbraco/Umbraco-CMS/issues/13804 - https://discord-chats.umbraco.com/t/18810092/ambientcontext-error-when-trying-to-use-conentservice-within - https://cultiv.nl/blog/using-hangfire-to-update-umbraco-content/ Has anyone found a solution for this? Unfortunately it'll be a bit tricky for me to share the actual code
I have the service used by the Hangfire site set up as Scoped from Dependency Injection perspective too
n
Also, I think @nzdev shared some code that might help with this at some point (I can't find it though) so I'm hoping tagging him in this reply might prompt his memory :-)D
m
Hmm I'm using the following before my bit of code before using the IContentService etc, which looks to be what Shannon suggests, along with some suggestions from @User etc
Copy code
cs
using var backgroundScope = new BackgroundScope(_serverMessenger);
using var umbracoContext = _contextFactory.EnsureUmbracoContext();
using var serviceScope = _serviceProvider.CreateScope();
k
Stupid question, but can you verify that indexing failures occur when saving this way? If it's just a timing problem in the Examine/Scope teardown, maybe there's no real problem?
m
Hmmm, it may be a bit of a red herring, although we did get a database write lock at one point and it looks like it may have been related. That being said, it could have just been a random lost connection that locked the db, although i feel like that shouldn't happen so easily
n
public class BackgroundScope : IBackgroundScope { private readonly IServerMessenger _serverMessenger; public BackgroundScope(IServerMessenger serverMessenger) { _serverMessenger = serverMessenger; } public void Dispose() { if (_serverMessenger is BatchedDatabaseServerMessenger batchedDatabaseServerMessenger) { batchedDatabaseServerMessenger.SendMessages(); } } }
m
Yeah, i've got this set up as well
b
an older thread, but I thought it might be a good to add this here, as I've not exactly seen this solution anywhere, but pieces of it has been available here and there. 🙂 Long story short, we had similar issues, but had a wide variety of hangfire jobs in our solution, and they started to give similar errors and the issues described here as well: https://our.umbraco.com/forum/using-umbraco-and-getting-started/113065-the-scope-being-disposed-is-not-the-ambient-scope An example of a hangfire task that we are currently using:
Copy code
csharp
public async Task Run(PerformContext? performContext, CancellationToken cancellationToken)
{
    performContext.WriteLine("Starting the process");

    Task someWorkTask;
    
    using (ExecutionContext.SuppressFlow())
    {
        someWorkTask = Task.Run(async () =>
        {
            await _someService.SomeWorkAsync();
        }, cancellationToken);
    }

    await someWorkTask;

    performContext.WriteLine("Finishing the process");
}
the PerformContext is not super important obviously, but the position if the someWorkTask awaiting it is, otherwise hangfire would just fire and forget, but you'd have no control over it. It is quite a recent change, but it is in production now for a week, and we've not seen the scope issues since. Everything the others has written above also stands and we are also using them (BackgroundScope, contextfactory, serviceprovider etc.)
k
Very interesting, thanks!
36 Views