SlideShare une entreprise Scribd logo
1  sur  45
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

Redux. From twitter hype to production
Redux. From twitter hype to productionRedux. From twitter hype to production
Redux. From twitter hype to production
FDConf
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
Ran Mizrahi
 
Apache Aries Overview
Apache Aries   OverviewApache Aries   Overview
Apache Aries Overview
Ian Robinson
 

Tendances (20)

About Node.js
About Node.jsAbout Node.js
About Node.js
 
Serverless Java on Kubernetes
Serverless Java on KubernetesServerless Java on Kubernetes
Serverless Java on Kubernetes
 
Redux. From twitter hype to production
Redux. From twitter hype to productionRedux. From twitter hype to production
Redux. From twitter hype to production
 
Express JS
Express JSExpress JS
Express JS
 
Cli jbug
Cli jbugCli jbug
Cli jbug
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
 
Advanced VCL: how to use restart
Advanced VCL: how to use restartAdvanced VCL: how to use restart
Advanced VCL: how to use restart
 
COScheduler
COSchedulerCOScheduler
COScheduler
 
Introduction to Python Celery
Introduction to Python CeleryIntroduction to Python Celery
Introduction to Python Celery
 
Scala, docker and testing, oh my! mario camou
Scala, docker and testing, oh my! mario camouScala, docker and testing, oh my! mario camou
Scala, docker and testing, oh my! mario camou
 
Javascript TDD with Jasmine, Karma, and Gulp
Javascript TDD with Jasmine, Karma, and GulpJavascript TDD with Jasmine, Karma, and Gulp
Javascript TDD with Jasmine, Karma, and Gulp
 
Build RESTful API Using Express JS
Build RESTful API Using Express JSBuild RESTful API Using Express JS
Build RESTful API Using Express JS
 
Intro to Node
Intro to NodeIntro to Node
Intro to Node
 
Dropwizard Internals
Dropwizard InternalsDropwizard Internals
Dropwizard Internals
 
Autoscaling with hashi_corp_nomad
Autoscaling with hashi_corp_nomadAutoscaling with hashi_corp_nomad
Autoscaling with hashi_corp_nomad
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.x
 
Nodejs Explained with Examples
Nodejs Explained with ExamplesNodejs Explained with Examples
Nodejs Explained with Examples
 
Angular beans
Angular beansAngular beans
Angular beans
 
Apache Aries Overview
Apache Aries   OverviewApache Aries   Overview
Apache Aries Overview
 

Similaire à Scheduling tasks the human way - Brad Wood - ITB2021

How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
Ben Lin
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}
.toster
 

Similaire à Scheduling tasks the human way - Brad Wood - ITB2021 (20)

ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf
ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdfITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf
ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf
 
Google App Engine Developer - Day3
Google App Engine Developer - Day3Google App Engine Developer - Day3
Google App Engine Developer - Day3
 
Brad Wood - CommandBox CLI
Brad Wood - CommandBox CLI Brad Wood - CommandBox CLI
Brad Wood - CommandBox CLI
 
An Introduction to Celery
An Introduction to CeleryAn Introduction to Celery
An Introduction to Celery
 
Celery
CeleryCelery
Celery
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
 
Threads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSThreads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOS
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Integration-Monday-Stateful-Programming-Models-Serverless-Functions
Integration-Monday-Stateful-Programming-Models-Serverless-FunctionsIntegration-Monday-Stateful-Programming-Models-Serverless-Functions
Integration-Monday-Stateful-Programming-Models-Serverless-Functions
 
NodeJSnodesforfreeinmyworldgipsnndnnd.pdf
NodeJSnodesforfreeinmyworldgipsnndnnd.pdfNodeJSnodesforfreeinmyworldgipsnndnnd.pdf
NodeJSnodesforfreeinmyworldgipsnndnnd.pdf
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}
 
Building resilient scheduling in distributed systems with Spring
Building resilient scheduling in distributed systems with SpringBuilding resilient scheduling in distributed systems with Spring
Building resilient scheduling in distributed systems with Spring
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
Node js lecture
Node js lectureNode js lecture
Node js lecture
 
Grails transactions
Grails   transactionsGrails   transactions
Grails transactions
 
Dragoncraft Architectural Overview
Dragoncraft Architectural OverviewDragoncraft Architectural Overview
Dragoncraft Architectural Overview
 
Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
 

Plus de Ortus Solutions, Corp

Enterprise Messaging with RabbitMQ.pdf
Enterprise Messaging with RabbitMQ.pdfEnterprise Messaging with RabbitMQ.pdf
Enterprise Messaging with RabbitMQ.pdf
Ortus Solutions, Corp
 

Plus de Ortus Solutions, Corp (20)

BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Ortus Government.pdf
Ortus Government.pdfOrtus Government.pdf
Ortus Government.pdf
 
Luis Majano The Battlefield ORM
Luis Majano The Battlefield ORMLuis Majano The Battlefield ORM
Luis Majano The Battlefield ORM
 
Secure your Secrets and Settings in ColdFusion
Secure your Secrets and Settings in ColdFusionSecure your Secrets and Settings in ColdFusion
Secure your Secrets and Settings in ColdFusion
 
Daniel Garcia ContentBox: CFSummit 2023
Daniel Garcia ContentBox: CFSummit 2023Daniel Garcia ContentBox: CFSummit 2023
Daniel Garcia ContentBox: CFSummit 2023
 
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdfITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
 
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdfITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
 
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdfITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf
 
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdfITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
 
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdfITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
 
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdfITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf
 
ITB_2023_CBWire_v3_Grant_Copley.pdf
ITB_2023_CBWire_v3_Grant_Copley.pdfITB_2023_CBWire_v3_Grant_Copley.pdf
ITB_2023_CBWire_v3_Grant_Copley.pdf
 
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdfITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf
 
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdfITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf
 
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdfITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf
 
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdfITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
 
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdf
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdfITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdf
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdf
 
ITB2023 Developing for Performance - Denard Springle.pdf
ITB2023 Developing for Performance - Denard Springle.pdfITB2023 Developing for Performance - Denard Springle.pdf
ITB2023 Developing for Performance - Denard Springle.pdf
 
Enterprise Messaging with RabbitMQ.pdf
Enterprise Messaging with RabbitMQ.pdfEnterprise Messaging with RabbitMQ.pdf
Enterprise Messaging with RabbitMQ.pdf
 
Into The Box 2023 Keynote day 2
Into The Box 2023 Keynote day 2Into The Box 2023 Keynote day 2
Into The Box 2023 Keynote day 2
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Dernier (20)

Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 

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