SlideShare a Scribd company logo
Scheduling Tasks
The Human Way!
Brad Wood
@bdw429s
Scheduled Tasks
Scheduled Task Options Today
● Adobe Scheduled Tasks
(Uses Quartz engine)
● Lucee Scheduled Tasks
(Uses custom scheduler thread)
● Cron jobs/Jenkins jobs that hit URL
Completely external to the JVM
Scheduled Task Pain Points
● Limited scheduling capabilities
● LImited error handling
● Hard to cluster
● Each CF engine has different config
● External scheduling isn’t portable
● Can ‘t contribute run-time additions to scheduled tasks
● Usually based around public facing CFMs
● Not OO, not functional
What does the JDK Offer?
● The java.util.concurrent package!
● “Utility classes commonly useful in concurrent programming…
includes a few small standardized extensible frameworks… that
provide useful functionality and are otherwise tedious or difficult
to implement. “
● TimeUnit class for tracking seconds, minutes, hours, etc
● ThreadPoolExecutor and ScheduledThreadPoolExecutor
provide tunable, flexible thread pools.
ColdBox Scheduled Tasks
● NOT ACTUALLY COLDBOX SPECIFIC!! Also available in standalone
WireBox, LogBox, and CacheBox via the AsyncManager
● Define robust schedules via fluent DSL
● Uses Configuration as Code so no CF engine config and all contained in the
app
● Runs the same on all CF engines
● No external scheduling mechanism
● Built-in lifecycle methods and exception handling
● Built in clustering support to only run some tasks on one server
● Composable module-specific schedulers for drop-in HMVC functionality
ColdBox Scheduled Tasks
ColdBox Scheduled Tasks
Getting Started
ColdBox 6.2.0+
ColdBox Scheduler Convention
● Located in /config/Scheduler.cfc
● Our app templates are already updated to include it
● Works similar to Router.cfc-- automatic inheritance and
fluent DSL to call to configure the scheduler
ColdBox Scheduler Examples
component {
function configure() {
task( "my-task" )
.call( ()=log.info( 'Time keeps on ticking...' ) )
.everyMinute();
}
}
ColdBox Scheduler Examples
component {
function configure() {
task( "Clear Unregistered Users" )
.call( () => getInstance( "UserService" ).clearRecentUsers() )
.everyDayAt( "09:00" );
}
}
ColdBox Scheduler Examples
component {
function configure() {
task( "Hearbeat" )
.call( () => runEvent( "main.heartbeat" ) )
.every( 5, "minutes" )
.onFailure( ( task, exception ) => {
getInstance( "System" ).sendBadHeartbeat( exception );
} );
}
}
Scheduler Life-Cycle Methods
Scheduler Life-Cycle Methods
● onStartup() - Called after the scheduler has registered all schedules
● onShutdown() - Called before the scheduler is going to be shutdown
● onAnyTaskError(task,exception) - Called whenever ANY task fails
● onAnyTaskSuccess(task,result) - Called whenever ANY task succeeds
● beforeAnyTask(task) - Called before ANY task runs
● afterAnyTask(task,result) - Called after ANY task runs
Scheduler Life-Cycle Methods
component {
function configure() {
// Tasks here
}
function onStartup(){
log.info( 'Scheduler ready to rock and roll!' );
}
function onAnyTaskError( required task, required e ){
log.error( 'Task #task.getName()# has bombed!', e );
}
}
/config/Scheduler.cfc
Scheduler Configuration Methods
Scheduler Configuration Methods
● setCacheName( cacheName ) - Set the cachename to use for all
registered tasks
● setServerFixation( boolean ) - Set the server fixation to use for all
registered tasks
● setTimezone( timezone ) - Set the timezone to use for all registered tasks
● setExecutor( executor ) - Override the executor generated for the
scheduler
Scheduler Configuration Methods
component {
function configure() {
setCacheName( "Redis" );
setServerFixation( true );
setTimezone( "America/Chicago" );
}
}
/config/Scheduler.cfc
Scheduler Additional Methods
● getSetting()
● getInstance()
● runEvent()
● runRoute()
● view()
● layout()
● announce()
Task call() method
Task call() method
component {
function configure() {
// Lambda Syntax
task( "my-task" )
.call( () => getInstance( "myService" ).runcleanup() )
.everyHour();
}
}
/config/Scheduler.cfc
Task call() method
component {
function configure() {
// Closure Syntax
task( "my-task" )
.call( function(){
getInstance( "myService" ).runcleanup()
} )
.everyHourAt( 45 );
}
}
/config/Scheduler.cfc
Task call() method
component {
function configure() {
// Object with run() method
task( "my-task" )
.call( getInstance( "MyTask" ) )
.everyDay();
}
}
/config/Scheduler.cfc
Task call() method
component {
function configure() {
// Object with a custom method
task( "my-task" )
.call( getInstance( "CacheService" ), "reapCache" )
.everydayAt( "13:00" );
}
}
/config/Scheduler.cfc
Task Schedule Times
Scheduler TimeUnit
.every( period, timeunit )
.spacedDelay( spacedDelay, timeunit )
● days
● hours
● minutes
● seconds
● milliseconds (default)
● microseconds
● nanoseconds
Scheduler everyXXX() methods
.everydayAt( "13:00" )
.everyMinute()
.everyHour()
.everyHourAt( minutes )
.everyDay()
.everyDayAt( time )
.everyWeek()
.everyWeekOn( day, time )
.everyMonth()
.everyMonthOn( day, time )
Scheduler everyXXX() methods
.onFirstBusinessDayOfTheMonth( time )
.onLastBusinessDayOfTheMonth( time )
.everyYear()
.everyYearOn( month, day, time )
Scheduler everyXXX() methods
.onWeekends( time )
.onWeekdays( time )
.onMondays( time )
.onTuesdays( time )
.onWednesdays( time )
.onThursdays( time )
.onFridays( time )
.onSaturdays( time )
.onSundays( time )
Scheduler one-off tasks
component {
function configure() {
// Warm up caches 1 minute after app comes online
task( "build-up-cache" )
.call( () => getInstance( "DataServices" ).buildCache() )
.delay( 1, "minutes" );
}
}
/config/Scheduler.cfc
Task Life-Cycle Methods
Task Life-Cycle Methods
● after( target ) - Store the closure to execute after the task executes
● before( target ) - Store the closure to execute before the task executes
● onFailure( target ) - Store the closure to execute if there is a failure running
the task
● onSuccess( target ) - Store the closure to execute if the task completes
successfully
Task Life-Cycle Methods
task( "cool-task" )
.call( ()=>{} )
.before( function( task ) {
log.info( '#task.getName()# about to run!' );
} )
.after( function( task, results ){
log.info( '#task.getName()# has completed!' );
} )
.onFailure( function( task, exception ){
log.error( '#task.getName()# blew up!', exception );
} )
.onSuccess( function( task, results ){
log.info( '#task.getName()# has completed!' );
} );
/config/Scheduler.cfc
Task Constraints
Task Constraints - when()
component {
property name='drinkService' inject;
function configure() {
task( "remove-thirst" )
.call( () => drinkService.orderDrinks() )
.hourly()
.when( () => drinkService.isHappyHour() );
}
}
/config/Scheduler.cfc
Task Constraints - server fixation
component {
function configure() {
task( "my-task" )
.call( () => getInstance( "securityService" ).cleanOldUsers() )
.daily()
.onOneServer();
}
}
/config/Scheduler.cfc
Task Constraints - environment
component {
function configure() {
task( "my-task" )
.call( () => getInstance( "securityService" ).cleanOldUsers() )
.daily()
.onEnvironment( "staging,production" );
}
}
/config/Scheduler.cfc
Task Stats
Task Stats
● created - The timestamp of when the task was created in memory
● lastRun - The last time the task ran
● nextRun - When the task will run next
● totalFailures - How many times the task has failed execution
● totalRuns - How many times the task has run
● totalSuccess - How many times the task has run and succeeded
Task Stats
getInstance( 'appScheduler@coldbox' )
.getTaskRecord( 'testharness-Heartbeat' )
.task
.getStats()
Schedulers For Modules
Schedulers For Modules
● Every module can have its own scheduler!
● Injectable as cbScheduler@{moduleName}
● Lifecycle is tied to module load/unload
● Provides portable, drop in tasks
Schedulers For Modules - Example
task( "unleashsdk-refresh-features" )
.call( getInstance( "UnleashSDK@unleashsdk" ), "refreshFeatures" )
.every( variables.refreshInterval, "seconds" )
.before( function() {
if ( log.canDebug() ) {
log.debug( "Starting to fetch new features from Unleash" );
}
} )
.onSuccess( function( task, results ) {
if ( log.canInfo() ) {
log.info( "Successfully refreshed features", results );
}
} )
.onFailure( function( task, exception ) {
if ( log.canError() ) {
log.error( "Exception when running task [unleashsdk-refresh-features]:", exception );
}
} );
https://github.com/coldbox-modules/unleashsdk/blob/main/config/Scheduler.cfc
The End (Q & A)
https://coldbox.ortusbooks.com/digging-deeper/scheduled-tasks
Brad Wood
@bdw429s
brad@bradwood.com

More Related Content

PPT
7. cara penanganan kesalahan
DOCX
ENCODER DAN DECODER.docx
PDF
Modul pelatihan praktikum mikrokontroler dengan software proteus
PDF
11g Function Result Cache
PPT
1.sınıf1h hücre yapisi ve bi̇leşenleri̇
PPSX
Bab iii transformasi z
PDF
Bab 6 rangkaian orde satu
PPTX
Cache memory
7. cara penanganan kesalahan
ENCODER DAN DECODER.docx
Modul pelatihan praktikum mikrokontroler dengan software proteus
11g Function Result Cache
1.sınıf1h hücre yapisi ve bi̇leşenleri̇
Bab iii transformasi z
Bab 6 rangkaian orde satu
Cache memory

Similar to Scheduling tasks the human way - Brad Wood - ITB2021 (20)

PDF
Revolutionizing Task Scheduling in CFML!
PDF
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
PPTX
Understanding Sitecore Schedulers: Configuration and Execution Guide
PDF
Revolutionizing Task Scheduling in ColdBox
PDF
Как сделать высоконагруженный сервис, не зная количество нагрузки / Олег Обле...
PDF
How I learned to time travel, or, data pipelining and scheduling with Airflow
DOCX
14 lab-planing
DOCX
14 lab-planing
PDF
Hadoop Summit San Jose 2015: Towards SLA-based Scheduling on YARN Clusters
PDF
From scheduled downtime to self-healing
PDF
Podila mesos con europe keynote aug sep 2016
PPTX
Schedulers optimization to handle multiple jobs in hadoop cluster
PDF
COScheduler
PPTX
Advanced workload scheduling for containers on AWS
PPTX
Towards SLA-based Scheduling on YARN Clusters
PPTX
Scheduling scheme for hadoop clusters
PDF
Survey on Job Schedulers in Hadoop Cluster
PDF
PDF
Internals of concurent managers
PPTX
Hadoop World 2011: Hadoop and Performance - Todd Lipcon & Yanpei Chen, Cloudera
Revolutionizing Task Scheduling in CFML!
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
Understanding Sitecore Schedulers: Configuration and Execution Guide
Revolutionizing Task Scheduling in ColdBox
Как сделать высоконагруженный сервис, не зная количество нагрузки / Олег Обле...
How I learned to time travel, or, data pipelining and scheduling with Airflow
14 lab-planing
14 lab-planing
Hadoop Summit San Jose 2015: Towards SLA-based Scheduling on YARN Clusters
From scheduled downtime to self-healing
Podila mesos con europe keynote aug sep 2016
Schedulers optimization to handle multiple jobs in hadoop cluster
COScheduler
Advanced workload scheduling for containers on AWS
Towards SLA-based Scheduling on YARN Clusters
Scheduling scheme for hadoop clusters
Survey on Job Schedulers in Hadoop Cluster
Internals of concurent managers
Hadoop World 2011: Hadoop and Performance - Todd Lipcon & Yanpei Chen, Cloudera
Ad

More from Ortus Solutions, Corp (20)

PDF
TheFutureIsDynamic-BoxLang witch Luis Majano.pdf
PDF
June Webinar: BoxLang-Dynamic-AWS-Lambda
PDF
BoxLang-Dynamic-AWS-Lambda by Luis Majano.pdf
PDF
What's-New-with-BoxLang-Brad Wood.pptx.pdf
PDF
Getting Started with BoxLang - CFCamp 2025.pdf
PDF
CFCamp2025 - Keynote Day 1 led by Luis Majano.pdf
PDF
What's New with BoxLang Led by Brad Wood.pdf
PDF
Vector Databases and the BoxLangCFML Developer.pdf
PDF
Using cbSSO in a ColdBox App Led by Jacob Beers.pdf
PDF
Use JSON to Slash Your Database Performance.pdf
PDF
Portable CI wGitLab and Github led by Gavin Pickin.pdf
PDF
Tame the Mesh An intro to cross-platform tracing and troubleshooting.pdf
PDF
Supercharging CommandBox with Let's Encrypt.pdf
PDF
Spice up your site with cool animations using GSAP..pdf
PDF
Passkeys and cbSecurity Led by Eric Peterson.pdf
PDF
Legacy Code Nightmares , Hellscapes, and Lessons Learned.pdf
PDF
Integrating the OpenAI API in Your Coldfusion Apps.pdf
PDF
Hidden Gems in FusionReactor for BoxLang, ACF, and Lucee Users.pdf
PDF
Geting-started with BoxLang Led By Raymon Camden.pdf
PDF
From Zero to CRUD with ORM - Led by Annette Liskey.pdf
TheFutureIsDynamic-BoxLang witch Luis Majano.pdf
June Webinar: BoxLang-Dynamic-AWS-Lambda
BoxLang-Dynamic-AWS-Lambda by Luis Majano.pdf
What's-New-with-BoxLang-Brad Wood.pptx.pdf
Getting Started with BoxLang - CFCamp 2025.pdf
CFCamp2025 - Keynote Day 1 led by Luis Majano.pdf
What's New with BoxLang Led by Brad Wood.pdf
Vector Databases and the BoxLangCFML Developer.pdf
Using cbSSO in a ColdBox App Led by Jacob Beers.pdf
Use JSON to Slash Your Database Performance.pdf
Portable CI wGitLab and Github led by Gavin Pickin.pdf
Tame the Mesh An intro to cross-platform tracing and troubleshooting.pdf
Supercharging CommandBox with Let's Encrypt.pdf
Spice up your site with cool animations using GSAP..pdf
Passkeys and cbSecurity Led by Eric Peterson.pdf
Legacy Code Nightmares , Hellscapes, and Lessons Learned.pdf
Integrating the OpenAI API in Your Coldfusion Apps.pdf
Hidden Gems in FusionReactor for BoxLang, ACF, and Lucee Users.pdf
Geting-started with BoxLang Led By Raymon Camden.pdf
From Zero to CRUD with ORM - Led by Annette Liskey.pdf
Ad

Recently uploaded (20)

PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
DP Operators-handbook-extract for the Mautical Institute
PDF
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
PPTX
Chapter 5: Probability Theory and Statistics
PDF
Hybrid model detection and classification of lung cancer
PDF
Getting Started with Data Integration: FME Form 101
PPTX
SOPHOS-XG Firewall Administrator PPT.pptx
PPTX
OMC Textile Division Presentation 2021.pptx
PPTX
Tartificialntelligence_presentation.pptx
PDF
Hindi spoken digit analysis for native and non-native speakers
PPTX
cloud_computing_Infrastucture_as_cloud_p
PDF
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
PDF
project resource management chapter-09.pdf
PPTX
1. Introduction to Computer Programming.pptx
PDF
Enhancing emotion recognition model for a student engagement use case through...
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
Programs and apps: productivity, graphics, security and other tools
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Digital-Transformation-Roadmap-for-Companies.pptx
DP Operators-handbook-extract for the Mautical Institute
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
Chapter 5: Probability Theory and Statistics
Hybrid model detection and classification of lung cancer
Getting Started with Data Integration: FME Form 101
SOPHOS-XG Firewall Administrator PPT.pptx
OMC Textile Division Presentation 2021.pptx
Tartificialntelligence_presentation.pptx
Hindi spoken digit analysis for native and non-native speakers
cloud_computing_Infrastucture_as_cloud_p
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
project resource management chapter-09.pdf
1. Introduction to Computer Programming.pptx
Enhancing emotion recognition model for a student engagement use case through...

Scheduling tasks the human way - Brad Wood - ITB2021

  • 1. Scheduling Tasks The Human Way! Brad Wood @bdw429s
  • 3. Scheduled Task Options Today ● Adobe Scheduled Tasks (Uses Quartz engine) ● Lucee Scheduled Tasks (Uses custom scheduler thread) ● Cron jobs/Jenkins jobs that hit URL Completely external to the JVM
  • 4. Scheduled Task Pain Points ● Limited scheduling capabilities ● LImited error handling ● Hard to cluster ● Each CF engine has different config ● External scheduling isn’t portable ● Can ‘t contribute run-time additions to scheduled tasks ● Usually based around public facing CFMs ● Not OO, not functional
  • 5. What does the JDK Offer? ● The java.util.concurrent package! ● “Utility classes commonly useful in concurrent programming… includes a few small standardized extensible frameworks… that provide useful functionality and are otherwise tedious or difficult to implement. “ ● TimeUnit class for tracking seconds, minutes, hours, etc ● ThreadPoolExecutor and ScheduledThreadPoolExecutor provide tunable, flexible thread pools.
  • 6. ColdBox Scheduled Tasks ● NOT ACTUALLY COLDBOX SPECIFIC!! Also available in standalone WireBox, LogBox, and CacheBox via the AsyncManager ● Define robust schedules via fluent DSL ● Uses Configuration as Code so no CF engine config and all contained in the app ● Runs the same on all CF engines ● No external scheduling mechanism ● Built-in lifecycle methods and exception handling ● Built in clustering support to only run some tasks on one server ● Composable module-specific schedulers for drop-in HMVC functionality
  • 10. ColdBox Scheduler Convention ● Located in /config/Scheduler.cfc ● Our app templates are already updated to include it ● Works similar to Router.cfc-- automatic inheritance and fluent DSL to call to configure the scheduler
  • 11. ColdBox Scheduler Examples component { function configure() { task( "my-task" ) .call( ()=log.info( 'Time keeps on ticking...' ) ) .everyMinute(); } }
  • 12. ColdBox Scheduler Examples component { function configure() { task( "Clear Unregistered Users" ) .call( () => getInstance( "UserService" ).clearRecentUsers() ) .everyDayAt( "09:00" ); } }
  • 13. ColdBox Scheduler Examples component { function configure() { task( "Hearbeat" ) .call( () => runEvent( "main.heartbeat" ) ) .every( 5, "minutes" ) .onFailure( ( task, exception ) => { getInstance( "System" ).sendBadHeartbeat( exception ); } ); } }
  • 15. Scheduler Life-Cycle Methods ● onStartup() - Called after the scheduler has registered all schedules ● onShutdown() - Called before the scheduler is going to be shutdown ● onAnyTaskError(task,exception) - Called whenever ANY task fails ● onAnyTaskSuccess(task,result) - Called whenever ANY task succeeds ● beforeAnyTask(task) - Called before ANY task runs ● afterAnyTask(task,result) - Called after ANY task runs
  • 16. Scheduler Life-Cycle Methods component { function configure() { // Tasks here } function onStartup(){ log.info( 'Scheduler ready to rock and roll!' ); } function onAnyTaskError( required task, required e ){ log.error( 'Task #task.getName()# has bombed!', e ); } } /config/Scheduler.cfc
  • 18. Scheduler Configuration Methods ● setCacheName( cacheName ) - Set the cachename to use for all registered tasks ● setServerFixation( boolean ) - Set the server fixation to use for all registered tasks ● setTimezone( timezone ) - Set the timezone to use for all registered tasks ● setExecutor( executor ) - Override the executor generated for the scheduler
  • 19. Scheduler Configuration Methods component { function configure() { setCacheName( "Redis" ); setServerFixation( true ); setTimezone( "America/Chicago" ); } } /config/Scheduler.cfc
  • 20. Scheduler Additional Methods ● getSetting() ● getInstance() ● runEvent() ● runRoute() ● view() ● layout() ● announce()
  • 22. Task call() method component { function configure() { // Lambda Syntax task( "my-task" ) .call( () => getInstance( "myService" ).runcleanup() ) .everyHour(); } } /config/Scheduler.cfc
  • 23. Task call() method component { function configure() { // Closure Syntax task( "my-task" ) .call( function(){ getInstance( "myService" ).runcleanup() } ) .everyHourAt( 45 ); } } /config/Scheduler.cfc
  • 24. Task call() method component { function configure() { // Object with run() method task( "my-task" ) .call( getInstance( "MyTask" ) ) .everyDay(); } } /config/Scheduler.cfc
  • 25. Task call() method component { function configure() { // Object with a custom method task( "my-task" ) .call( getInstance( "CacheService" ), "reapCache" ) .everydayAt( "13:00" ); } } /config/Scheduler.cfc
  • 27. Scheduler TimeUnit .every( period, timeunit ) .spacedDelay( spacedDelay, timeunit ) ● days ● hours ● minutes ● seconds ● milliseconds (default) ● microseconds ● nanoseconds
  • 28. Scheduler everyXXX() methods .everydayAt( "13:00" ) .everyMinute() .everyHour() .everyHourAt( minutes ) .everyDay() .everyDayAt( time ) .everyWeek() .everyWeekOn( day, time ) .everyMonth() .everyMonthOn( day, time )
  • 29. Scheduler everyXXX() methods .onFirstBusinessDayOfTheMonth( time ) .onLastBusinessDayOfTheMonth( time ) .everyYear() .everyYearOn( month, day, time )
  • 30. Scheduler everyXXX() methods .onWeekends( time ) .onWeekdays( time ) .onMondays( time ) .onTuesdays( time ) .onWednesdays( time ) .onThursdays( time ) .onFridays( time ) .onSaturdays( time ) .onSundays( time )
  • 31. Scheduler one-off tasks component { function configure() { // Warm up caches 1 minute after app comes online task( "build-up-cache" ) .call( () => getInstance( "DataServices" ).buildCache() ) .delay( 1, "minutes" ); } } /config/Scheduler.cfc
  • 33. Task Life-Cycle Methods ● after( target ) - Store the closure to execute after the task executes ● before( target ) - Store the closure to execute before the task executes ● onFailure( target ) - Store the closure to execute if there is a failure running the task ● onSuccess( target ) - Store the closure to execute if the task completes successfully
  • 34. Task Life-Cycle Methods task( "cool-task" ) .call( ()=>{} ) .before( function( task ) { log.info( '#task.getName()# about to run!' ); } ) .after( function( task, results ){ log.info( '#task.getName()# has completed!' ); } ) .onFailure( function( task, exception ){ log.error( '#task.getName()# blew up!', exception ); } ) .onSuccess( function( task, results ){ log.info( '#task.getName()# has completed!' ); } ); /config/Scheduler.cfc
  • 36. Task Constraints - when() component { property name='drinkService' inject; function configure() { task( "remove-thirst" ) .call( () => drinkService.orderDrinks() ) .hourly() .when( () => drinkService.isHappyHour() ); } } /config/Scheduler.cfc
  • 37. Task Constraints - server fixation component { function configure() { task( "my-task" ) .call( () => getInstance( "securityService" ).cleanOldUsers() ) .daily() .onOneServer(); } } /config/Scheduler.cfc
  • 38. Task Constraints - environment component { function configure() { task( "my-task" ) .call( () => getInstance( "securityService" ).cleanOldUsers() ) .daily() .onEnvironment( "staging,production" ); } } /config/Scheduler.cfc
  • 40. Task Stats ● created - The timestamp of when the task was created in memory ● lastRun - The last time the task ran ● nextRun - When the task will run next ● totalFailures - How many times the task has failed execution ● totalRuns - How many times the task has run ● totalSuccess - How many times the task has run and succeeded
  • 41. Task Stats getInstance( 'appScheduler@coldbox' ) .getTaskRecord( 'testharness-Heartbeat' ) .task .getStats()
  • 43. Schedulers For Modules ● Every module can have its own scheduler! ● Injectable as cbScheduler@{moduleName} ● Lifecycle is tied to module load/unload ● Provides portable, drop in tasks
  • 44. Schedulers For Modules - Example task( "unleashsdk-refresh-features" ) .call( getInstance( "UnleashSDK@unleashsdk" ), "refreshFeatures" ) .every( variables.refreshInterval, "seconds" ) .before( function() { if ( log.canDebug() ) { log.debug( "Starting to fetch new features from Unleash" ); } } ) .onSuccess( function( task, results ) { if ( log.canInfo() ) { log.info( "Successfully refreshed features", results ); } } ) .onFailure( function( task, exception ) { if ( log.canError() ) { log.error( "Exception when running task [unleashsdk-refresh-features]:", exception ); } } ); https://github.com/coldbox-modules/unleashsdk/blob/main/config/Scheduler.cfc
  • 45. The End (Q & A) https://coldbox.ortusbooks.com/digging-deeper/scheduled-tasks Brad Wood @bdw429s brad@bradwood.com