3

We are using the new Sitecore Publishing Service (SPS) and trying to hook into the BulkPublishingEnd event. We have the following patch:

<publishEndResultBatch>
    <processor type="Foobar.Feature.Website.Pipelines.PublishBatchResultProcessor, Foobar.Feature.Website"
               patch:after="*[@type='Sitecore.Publishing.Service.Pipelines.BulkPublishingEnd.RaiseRemoteEvents, Sitecore.Publishing.Service']" />
</publishEndResultBatch>

I verified that the config is correct:

  <publishEndResultBatch patch:source="Sitecore.Publishing.Service.config" argsType="Sitecore.Publishing.Service.Pipelines.BulkPublishingEnd.PublishEndResultBatchArgs">
    <processor type="Sitecore.Publishing.Service.Pipelines.BulkPublishingEnd.RaiseRemoteEvents, Sitecore.Publishing.Service">
        <param name="remoteEventCacheClearingThreshold">1000</param>
        <param name="targetCacheClearHistory" ref="publishing.service/targetCacheClearHistory"/>
    </processor>
    <processor patch:source="z-PublishPipeline.config" type="Foobar.Feature.Website.Pipelines.PublishBatchResultProcessor, Foobar.Feature.Website"/>
  </publishEndResultBatch>  

The process runs correctly and reports on the items that were published. However, when I access the items directly in the target DB, I'm getting back the pre-updated item:

var db = Sitecore.Configuration.Factory.GetDatabase(args.TargetInfo.TargetDatabaseName);
var item = db.GetItem(publishedItem.EntityId.ToID());  

My results in the immediate window after stepping through the code above are as follows:

args.Batch[0].Metadata.AsModified().ModifiedFields.ToArray()[0]
{Sitecore.Framework.Publishing.Manifest.FieldResult}
   ChangeType: Modified
   FieldId: {8cdc337e-a112-42fb-bbb4-4143751e123f}
   Language: "en"
   OriginalValue: "0829f0a6-260d-4a74-b7c2-0e27b063845a"
   Value: "e0b4938c-4d6a-4891-94ab-b5d606a6df01"
   Version: 1

item.Fields["{8cdc337e-a112-42fb-bbb4-4143751e123f}"].Value
"0829f0a6-260d-4a74-b7c2-0e27b063845a"

In my Process, I'm also initiating a re-index of a related item, using IndexCustodian.Refresh(...). When the re-index runs, it too has the original revision of the published items.

If I create a new item and publish, I get back the newly created item, in both instances, like I expect.

Is this intended behavior? Am I missing something in my config? Maybe the cache isn't getting cleared correctly? Is there another location in the pipeline that I can hook into and get both:

a) a list of changed items

b) context after the items have been updated and the cache cleared.

1

Edit 14/6/17: This has indeed been fixed in v2.0 Update 1 (release notes)

The reason you are seeing the pre-updated Items is because the data caches in the authoring instance for the Web DB are stale at the time the publish:end event is executed (in the authoring instance). I.e the events that trigger the clearing of the caches of 'web' data in the authoring site have not been handled before your publish:end handler is triggered.

This is a bug that we are working to fix for v2 Update 1, out in the next month or so.

  • I have installed Update 1 and I'm still getting stale data in my PublishBatchResultProcessor and during the index refresh. I did notice that publish:end:remote seems to have the correct data. I want to double check that i have the correct publishing service installed. Where can I look up the version number? – BFK Jun 19 '17 at 19:37
  • The 'FileVersion' of the Sitecore.Publishing.Service.dll for 2.0.1 is 2.0.0.264. – Trevor Reeves Jun 21 '17 at 13:55
0

I found that clearing the item from all the caches fixes the issue. From what I've read this is supposed to already occur in the Sitecore.Publishing.Service.Pipelines.BulkPublishingEnd.RaiseRemoteEvents processor and therefore specifying the custom processor after this processor, I would have access to post-publish data.

I added the following code to the custom processor. My only concern with this approach, is the impact on site performance. I don't seem to be able to clear a single item from the prefetch cache, like the other caches. Does anyone know if there is a way to do this?

...
var db = Sitecore.Configuration.Factory.GetDatabase(args.TargetInfo.TargetDatabaseName);
var prefetch = GetPrefetchCache(db);
prefetch.Clear();

foreach (var publishedItem in args.Batch)
{
    var id = publishedItem.EntityId.ToID();
    _ClearFromCache(db, id);
    var item = db.GetItem(id);
...


private void _ClearFromCache(Database db, ID itemID)
{

    db.Caches.DataCache.RemoveItemInformation(itemID);

    //clear item cache
    db.Caches.ItemCache.RemoveItem(itemID);

    //clear standard values cache
    db.Caches.StandardValuesCache.RemoveKeysContaining(itemID.ToString());

    //remove path cache
    db.Caches.PathCache.RemoveKeysContaining(itemID.ToString());

    var prefetch = GetPrefetchCache(db);
    prefetch.Clear();
}

private static ICacheInfo GetPrefetchCache(Database database)
{
    return
        global::Sitecore.Caching.CacheManager.GetAllCaches()
              .FirstOrDefault(cache => cache.Name.Contains($"Prefetch data({database.Name})"));
}
  • The prefetch cache will cast to Sitecore.Caching.Generics.ICache<Sitecore.Data.ID>. This has a Remove(ID) function. You're in dangerous territory though, there's more clearing to be done - see inside Sitecore.Publishing.Service.Delivery.dll->TargetDataCacheClearHandler.cs for all that needs to be done. – Trevor Reeves May 18 '17 at 14:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.