Brian McKeiver's Blog

Kentico MVC Quick Tip - Fix Scheduled Content


Introduction

When troubleshooting an issue, do you ever have that feeling of, "well...this should just work, it always just works..." ? Yeah, I get that a lot. In fact, today's quick tip on Kentico MVC gave me this feeling at least 3 times during a project I was recently on. I was tasked with figuring out why page content in our upgraded Kentico EMS 12.0 site was not publishing automatically when the publish from date was set in the future and that time had passed.

The thing is, the ability to have content scheduled to be published in the future has been in the Kentico platform for ages. I'd guess it was probably there all the way back in version 4 or version 5 of the CMS (maybe even earlier). The feature hasn't really changed in any version I can remember. It should. just. work. I didn't think it had anything to do with MVC vs. Portal engine either, because this feature is only really part of the Kentico Administration tool, and not the MVC live site. My head immediately went to the fact it could be a caching issue (it's almost always a caching issue right?), or server side time zone issue, or heck, in the US we just went through the daylight savings time zone change, maybe it was that. But I was wrong on all accounts.  

 

The Problem

Just in case you haven't went through this before, the basic idea of scheduling content to be published in the future is handled through configuration of the publish from date on a peice of content. 

 

KenticoScheduledContent_PublishFrom.png

 

When the date is set in the future, the status icon of a page in the content tree turns to the blue "New version waiting to be published" icon. 

 

KenticoScheduledContent.png

 

Then the system is supposed to automatically publish the content when that time arrives. And it will flip the page status icon to green, meaning published. The way this works is through an out of the box scheduled task called Content Publishing. But what is a bit strange is that it is not a global scheduled task, but instead a site specific scheduled task. That means it needs to be associated and running for each site in your Kentico installation. That scheduled task looks like:

 

KenticoScheduledContentPublishTask.png

 

Basically it runs every single minute to determine if something should be published or not. However, you have a problem if your site specific task list looks like this. Remember to change the site dropdown from (global) to your specific site.

 

KenticoScheduledContent_Problem.png

 

As soon as I found that on my project, I figured that oh, it's simple, we just need to add in the scheduled task and it should work. Well, as it turns out, that was only a portion of the solution...

Also, a quick side note, you might be asking, well how did a site get created with no site specific scheduled tasks in the first place? Well, that comes down to the fact that we start our projects at BizStream following the Kentico documentation for Starting with MVC Development as any good developer should. And if you follow those steps to create a new blank MVC site, this will be the result every time in Kentico 11 (and I'm guessing v10 as well).

 

 

Enter the Real Solution

The solution comes down to number 1, fixing the scheduled task situation. You have two options for that. You can either simply look at another instance or site that has the correct set of scheduled tasks for a specific site, and manually create the tasks that point at the right namespace and classes to create the fix, or the much better way, would be to export a set of site objects that represent the set of scheduled tasks from a good instance and import them into your instance that has the issue. You can follow the linked documentation there to do this if you are not sure how.  

When you have the correctly imported your site specific scheduled tasks should look like this:

 

KenticoScheduledContent_Fix.png

 

But as I mentioned above, this is only half the battle. The fun thing with Kentico MVC is that the admin tool is typically deployed in a separate App Pool (or Azure App Service) from the MVC live site. And that means if you are not active in production (and maybe have a staging server where you create content and then use a tool like Content Staging or Compare for Kentico to get your content out to production), your production admin tool can fall asleep from inactivity. And if your admin tool is not active, then these scheduled tasks are not going to run every one minute. Which puts you right back into this same problem of not getting scheduled content to publish in production.

To fix that problem you need to do a second step. Which in my experience, many Kentico developers miss in their setup. You need to also enable the correct Automatic Scheduler mode via the Kentico documentation. The main step of that is to include the following in your Kentico admin tool's root web.config:

 

<add key="CMSUseAutomaticScheduler" value="true"></add>

 

This configuration will send a GET request to this route (~/CMSPages/Scheduler.ashx) on your Kentico admin tool every 1 minute (which is a setting that can be changed) to keep the admin tool alive. Now you do need to also either enable the AlwaysOn setting in your Azure App Service, or IIS Website. In Azure this works great. But on-premise IIS it gets a little tricky with mixed results of actually keeping your admin tool 100% alive. We actually ended up enabling an outsite service to ping the admin tool URL every 5 minutes just to be sure.

 

Bottom line: If you ensure the correct site specific Content Publishing scheduled task is there for your site, and you have the Automatic Scheduler setup for your Kentico Admin tool setup, you can be assured your content will correctly publish automatically.

 

 

Conclusion

The good news is that this seems to be resolved in Kentico 12.0 builds. I was about to prove it worked out of the box on new clean 12.0 installs at various hotfix and service pack levels. However, if you have upgraded from Kentico 10 or Kentico 11 to Kentico 12 you might still have this problem. Hopefully I have saved you some time from thinking this should just work. Until next time.