Introducing Last Schedule

Hello world! It’s time to introduce my new pet-project to you. Please meet LastSchedule – yet another job scheduling solution for D365/CRM (that was it second name I was thinking of). Why did I built it? The answer is same as for D365Extentions: I was a little bit tired of doing the same things on each project and finally decided to build dedicated reusable solution. As a bonus it lets me play with CI stuff for D365 customization packaging – the thing I was always wanted to try.

The problem… Some times (every particular project) you need to execute some logic on regular bases. In most cases you need this to build some internal system logic or integrations. But there are user oriented use cases such as birthday reminders or neglected leads notifications or similar. Platform itself has this functionality (goals or rollup fields are calculated recurrently) but it is not shared with us as the developers.

The solution… is to use recurring workflow process. Process does the job, waits for required amount if time and then execute itself once again. The idea is not new and there are few similar implementations there and there, but they all have several disadvantages.

Before getting into details one thing should be clarified:

Do not fear the waiting workflows! They are completely OK and are not affecting system performance

It is common misconception that system has to execute them each second to understand if it is right time to continue. This statement is wrong as this processes (as well as other recurring jobs) are scheduled to be executed only once at some point of time in future. Asynchronous processing service is smart enough to calculate execution plan and run it effectively without need to constantly query DB or do other unnecessary things. If you’re still in doubt, remember that SLA functionality is build on top of waiting workflows! Yes, it is! SLA is something that can run for thousands of cases in the same time. If waiting workflows there not resource effective, Microsoft would never used them for building SLAs.

So what does make LastSchedule unique?

  • Recurrence jobs can share common schedules. Most likely you have the same cadence for several jobs. This centralizes and simplifies job management
  • Uses widely implemented Cron syntax. Cron syntax becomes industry standard for scheduling. It’s expressions are more powerful and flexible than predefined recurrence patterns.
  • Efficient processing and execution. Solution logic is driven by plugins and Custom Actions but not Custom Workflow Activities. May be it’s even worse as main loop process is hosted by a workflow, but in general this approach used to be faster
  • Easy job life cycle management. No need to execute and stop processes manually. Everything is done out of the box

Setup is simple:

Step 1. Download and import solution as usual. Then open setting app:

App

Step 2. Create schedule:

Schedule

Recurrence pattern is given in Quartz.NET Cron syntax dialect. For simplicity you can use CronMaker online tool to generate pattern.

Step 3. Create job and corresponding workflow process

Job

Give a name for new job, select schedule created on previous step, and process to be executed when job runs. Query parameter is optional. If it is provided, selected process will be executed against each record returned by the query, if not provided – process will be executed against Job record itself.

Important notice! Process should be a published background (asynchronous) workflow, enabled to run on-demand and as child process, such as shown bellow:

Workflow

Step 4. Publish the job

Simply change status reason to “Published”. To deactivate process set status reason back to “Draft” (or deactivate job record).

Publish

As said before, currently this solution is very basic and more features are coming soon. Please don’t hesitate to open issues and vote for favorite features to be implemented first.

One more thing to consider:

This solution (and any other solution using requiring workflows) has a huge limitation: you can't execute one job more than 15 times per 24 hours (approx. more than once per every 1,5 hour). If you try to execute more often, platform will consider your job as infinite loop and will terminate job after 15 executions. This issue will be addressed in next release

Happy scheduling and stay tuned!

p.s. The most difficult part at the moment, was to setup CI/CD pipeline for the solution. It was required as I decided to ship minimal valuable product and add more features later. Please let me know in the comments if you want me to share my findings in future posts 😉

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.