U4-7129 - Allow cache refreshers to run on a background thread even when batched messaging is on

Created by Shannon Deminick 22 Sep 2015, 13:13:57 Updated by Shannon Deminick 23 Sep 2015, 08:19:36

shazwazza [2:43 PM] Just committed some code if you can have a look, but this might only 'fix' very few edge case scenarios. The bigger issue is that Courier can call cache refreshers on a background thread. In which case our batched server messengers will always fail since there is never any batch since there is not HttpContext. For example, a common stack trace I've seen is:

   at Umbraco.Web.BatchedDatabaseServerMessenger.GetBatch(Boolean ensureHttpContext)
   at Umbraco.Web.BatchedDatabaseServerMessenger.BatchMessage(IEnumerable`1 servers, ICacheRefresher refresher, MessageType messageType, IEnumerable`1 ids, Type idType, String json)
   at Umbraco.Web.BatchedDatabaseServerMessenger.DeliverRemote(IEnumerable`1 servers, ICacheRefresher refresher, MessageType messageType, IEnumerable`1 ids, String json)
   at Umbraco.Core.Sync.ServerMessengerBase.Deliver(IEnumerable`1 servers, ICacheRefresher refresher, MessageType messageType, IEnumerable`1 ids, String json)
   at Umbraco.Core.Sync.ServerMessengerBase.PerformRefresh(IEnumerable`1 servers, ICacheRefresher refresher, String jsonPayload)
   at Umbraco.Web.Cache.DistributedCache.RefreshByJson(Guid factoryGuid, String jsonPayload)
   at Umbraco.Web.Cache.DistributedCacheExtensions.RefreshMacroCache(DistributedCache dc, IMacro macro)
   at Umbraco.Courier.Persistence.CacheHelper.ClearMacroCache(String macroAlias, IMacroService macroService)
   at Umbraco.Courier.DataResolvers.Events.FlushMacroCache.Execute(ItemIdentifier itemId, SerializableDictionary`2 parameters)

We should somehow make it possible to call dist cache from background threads too... not sure how tough that will be ? Off the top of my head it seems it shouldn't be too difficult because we can detect at the start if there's not HttpContext (using the same logic i just committed) and if there isn't then it knows it's not working with batches. What do you think ?

zpqrtbnk [3:01 PM] DeliverRemote() is trying to add stuff to the batch, so it can be processed later on. And then everything that's been batched is written out to database as one single instruction. Of course we could tweak DeliverRemote() to write each change immediately to database, if it cannot batch. Relatively easy to do.

zpqrtbnk [3:02 PM] Alternatively we'd need another way of providing a "context". That'd be much nicer and would help get rid of the httpContext dependency, but it could be quite complex.

zpqrtbnk [3:03 PM] Non-batching will work, the only issue is the pressure put on the database... edit 100 documents = 100 writes instead of 1...

zpqrtbnk [3:07 PM] But we may have to do it for the time being. Running without httpContext would require Courier to initialize some sort of alternate context, then do its own stuff in 1 thread (or carry that context from thread to thread), then signal that it's done, so we know we can flush the batch. That'd be the clean way, but expensive to do now.

shazwazza [3:11 PM] yup agree. I think courier doesn't do a lot of this so i think the db inserts would be relatively small... especially considering the courier is insanely high on the db usage spectrum :wink:


Stephan 22 Sep 2015, 16:22:20

Pushed 3124ea4e676aa4b70716c913f4a9085756c436e4 - @Shandem let me know if it works for you

Stephan 23 Sep 2015, 07:53:05

Assuming it's OK

Shannon Deminick 23 Sep 2015, 08:19:36

Will review the code today, @sebastiaan will test the changes with the issues we were seeing with courier.

Priority: Normal

Type: Task

State: Fixed

Assignee: Stephan

Difficulty: Normal


Backwards Compatible: True

Fix Submitted:

Affected versions:

Due in version: 7.3.0


Story Points: