Kevin Jump
08/09/2023, 1:32 PMScopedNotificationPublisher
then I've noticed that the notifications still go through one at a time, rather than say their being one ContentSavedNotification
with all the savedEntites
, I get an individual notification for each entity. each containing just a single item.
Is this by design ? or have I missed a thingy somewhere on the whole suppress / publish workflow where it will combine them ?
not a biggie but if there is a flag/method or something - it would be nice to give it a go.Kevin Jump
08/09/2023, 2:16 PMRonald Barendse
08/09/2023, 2:25 PMIDistributedCacheNotificationHandler
marker interface should be used for 😉
There's a couple of things that need to happen/align before you can handle multiple notifications:
1. Notifications need to be published within an Umbraco scope (as ScopedNotificationPublisher
will publish them when the scope is completed/disposed)
2. They are chunked/only grouped when multiple consecutive notifications of the same type are published, see https://github.com/umbraco/Umbraco-CMS/pull/14332#discussion_r1219303413
3. The `INotificationHandler`/`INotificationAsyncHandler` interfaces have a default implementation that iterates over the notifications for backwards compatibility, so you need to manually override thisKevin Jump
08/09/2023, 2:32 PMRonald Barendse
08/09/2023, 2:44 PMScopedNotificationPublisher
(by default) won't publish cancellable notifications on scope exit, as that would prevent you from actually cancelling the notification.
However, in Deploy we do suppress all events in a subclassed publisher that sets publishCancelableNotificationOnScopeExit: true
and overriding PublishScopedNotifications(...)
to group all notifications by type (to ensure they are all chunked/grouped together) and only publish them to handlers that implement `IDistributedCacheNotificationHandler`:
csharp
// Group notifications by type, since we don't care about the original order they were published in
var groupedNotifications = notifications.GroupBy(x => x.GetType()).SelectMany(x => x);
// Handle all distributed cache refreshers (including Deploy refreshers)
_eventAggregator.Publish<INotification, IDistributedCacheNotificationHandler>(groupedNotifications);
This is all fine, because we don't care about the order of notifications when updating the distributed caches (cache refreshers, which are used for updating NuCache, IAppCaches and Examine indexes) or the notification state... The base class for these handlers therefore only return the entities of all notifications: https://github.com/umbraco/Umbraco-CMS/blob/contrib/src/Umbraco.Core/Cache/NotificationHandlers/DistributedCacheNotificationHandlerBase.cs
You could achieve something similar by suppressing all notifications and manually rebuilding all caches, which is still how it's done within migrations:
- https://github.com/umbraco/Umbraco-CMS/blob/contrib/src/Umbraco.Infrastructure/Migrations/MigrationPlanExecutor.cs#L252
- https://github.com/umbraco/Umbraco-CMS/blob/contrib/src/Umbraco.Infrastructure/Migrations/MigrationPlanExecutor.cs#L107Kevin Jump
08/09/2023, 2:50 PMRonald Barendse
08/09/2023, 2:51 PMKevin Jump
08/09/2023, 2:52 PMRonald Barendse
08/09/2023, 3:02 PM