From c920afbfb7f6f385df4a555ae2ab6287e25c5da5 Mon Sep 17 00:00:00 2001 From: macolso Date: Tue, 1 Apr 2025 20:38:14 -0700 Subject: [PATCH 1/6] added cron tutorial Signed-off-by: macolso --- content/wasm-functions/using-cron-trigger.md | 170 +++++++++++++++++-- templates/functions_sidebar.hbs | 1 + 2 files changed, 158 insertions(+), 13 deletions(-) diff --git a/content/wasm-functions/using-cron-trigger.md b/content/wasm-functions/using-cron-trigger.md index cc59c22af..7fa61907e 100644 --- a/content/wasm-functions/using-cron-trigger.md +++ b/content/wasm-functions/using-cron-trigger.md @@ -7,18 +7,20 @@ enable_shortcodes = true - [Prerequisites](#prerequisites) - [Introduction to Cron Jobs](#introduction-to-cron-jobs) - [What Are Cron Jobs?](#what-are-cron-jobs) -- [Spin and Fermyon Wasm Functions](#spin-and-fermyon-wasm-functions) - - [Create Spin application](#create-spin-application) - - [Creating a Cron Job for your Spin application](#creating-a-cron-job-for-your-spin-application) - - [Managing Cron Jobs](#managing-cron-jobs) +- [Create Spin application](#create-spin-application) + - [Deploy Spin Application to Fermyon Wasm Functions](#deploy-spin-application-to-fermyon-wasm-functions) +- [Creating a Cron Job for Your Spin Application](#creating-a-cron-job-for-your-spin-application) +- [Managing Cron Jobs](#managing-cron-jobs) +- [Delete Cron Job](#delete-cron-job) +- [Next Steps](#next-steps) -This tutorial guides you through the process of scheduling HTTP requests in a Spin application running on Fermyon Wasm Functions using cron jobs. The `spin aka cron` command allows applications to receive scheduled HTTP triggers without relying on external services. In this tutorial, you'll learn how to define and manage cron jobs using the `spin aka cron` command. +This tutorial guides you through the process of scheduling HTTP requests in a Spin application running on Fermyon Wasm Functions using cron jobs. The `spin aka crons` command allows applications to receive scheduled HTTP triggers without relying on external services. In this tutorial, you'll learn how to define and manage cron jobs using the `spin aka crons` command. # Prerequisites Before proceeding, ensure you have the following: -- Spin installed on your machine (Installation Guide) -- Access to Fermyon Wasm Functions preview (Sign Up Form) +- Spin and the `spin aka` plugin installed on your machine ([Installation Guide](./quickstart.md)) +- Access to Fermyon Wasm Functions preview ([Sign Up Form](https://fibsu0jcu2g.typeform.com/fwf-preview)) # Introduction to Cron Jobs @@ -32,16 +34,158 @@ Use Cases for Cron Jobs: * Log file rotation * Scheduled notifications -# Spin and Fermyon Wasm Functions +# Create Spin application -Spin is a lightweight framework for building WebAssembly microservices and applications. It allows developers to define cron jobs that execute functions at scheduled intervals. To simplify development, Spin provides templates for various use cases, including scheduled tasks. +You must have a running Spin application on Fermyon Wasm Functions to apply the cron trigger to. We'll create a new Spin application for scheduling tasks using cron jobs using the `http-js` template: -## Create Spin application + -You must have a running Spin application on Fermyon Wasm Functions to apply the cron trigger to. We'll create a new Spin application for scheduling tasks using cron jobs: +```console +$ spin new -t http-js --accept-defaults hello-cron-job +$ cd hello-cron-job +$ npm install +``` -## Creating a Cron Job for your Spin application +We'll go ahead add a specific path for our cron trigger in later steps: -## Managing Cron Jobs +```toml +[[trigger.http]] +route = "/hello" +component = "hello-cron-job" +``` + +Let's modify the response body so we can validate that our application is running on a specific interval. To do so, navigate to `src/index.js` and add the following snippet of code: + + + +```JavaScript +// For AutoRouter documentation refer to https://itty.dev/itty-router/routers/autorouter +import { AutoRouter } from 'itty-router'; + +let router = AutoRouter(); + +// Route ordering matters, the first route that matches will be used +// Any route that does not return will be treated as a middleware +// Any unmatched route will return a 404 +router + .get("/hello", () => { + // Grab datetime + const now = new Date().toISOString(); + // Return response with time of invocation + return new Response(`Hello from a cron component at ${now}`, { status: 200 }); +}); + + +addEventListener('fetch', (event) => { + event.respondWith(router.fetch(event.request)); +}); +``` + +To test locally, run the following command: + + + +```console +spin build --up +``` + +If it is working as expected, you should see a message returned along the lines of (but with an accurate datetime): + + + +```console +curl localhost:3000 +``` + + + +```console +Hello from a cron component at 2025-03-31T21:45:25.562Z +``` + +## Deploy Spin Application to Fermyon Wasm Functions + +Before applying our cron trigger, we must have our Spin application running on the Fermyon Wasm Functions platform. Deploy the application with: + + + +```console +spin aka deploy +``` + +Upon successful deployment, you should receive a domain name that you can use to test the application: + + + +```console +curl https://ec8f3c23-b73d-4d51-aa69-aabd7ddc132a.aka.fermyon.tech/hello +Hello from a cron component at 2025-04-02T03:16:14.212Z% +``` + +# Creating a Cron Job for Your Spin Application + +Now we will use the `spin aka crons` command to invoke the Spin app's HTTP endpoint at our desired interval. The syntax for this request follows standard crontab format. + +> `spin aka cron` supports single digits in each cron expression field and intervals in every position except the day of the week (e.g., `* */12 * * *` for every 12 hours). The smallest supported cron configuration is every 5 minutes (`*/5 * * * *`). Other syntax elements like comma-separated lists and ranges are not supported. Please feel free to[leave feedback](https://fibsu0jcu2g.typeform.com/to/G2u4tPcP) if your desired range is not supported. + +Let's create a cron job that runs every hour. Since scheduling is based on UTC, you may need to [convert your local time to UTC](https://www.worldtimebuddy.com/?pl=1&lid=100&h=100&hf=1) to ensure correct execution. + + + +```console +spin aka crons create "0 * * * *" "/hello" "hello-cron-job" +``` + +You should see output similar to: + + + +```console +Created cron which will next run at 2025-04-02 04:00:00 UTC +``` + +# Managing Cron Jobs + +You can view all of your running cron jobs with: + + + +```console +spin aka crons list +``` + + + +```console ++----------------+-----------+-------------------------+ +| Name | Schedule | Next Run | ++======================================================+ +| hello-cron-job | 0 * * * * | 2025-04-02 04:00:00 UTC | ++----------------+-----------+-------------------------+ +``` + +You can have multiple cron jobs per Spin application. + +# Delete Cron Job + +To delete a cron job, use: + + + +```console +spin aka crons delete hello-cron-job +``` + + + +```console +Deleted cron job 'hello-cron-job' with schedule '0 * * * *' +``` + +Your application will persist unless you explicitly run the `spin aka apps delete` command. + +# Next Steps + +* Visit [FAQ](faq.md) for frequently asked questions. \ No newline at end of file diff --git a/templates/functions_sidebar.hbs b/templates/functions_sidebar.hbs index 83bb366d6..0a81acc5a 100644 --- a/templates/functions_sidebar.hbs +++ b/templates/functions_sidebar.hbs @@ -22,6 +22,7 @@ Integrating with Property Manager Using the Key Value Store + Using the Key Value Store Querying PostgreSQL Querying MySQL (Linode) Building a Supabase Cache Proxy From da629dac7053960afb42159b4773520b54c3c7d9 Mon Sep 17 00:00:00 2001 From: MacKenzie Olson Date: Wed, 2 Apr 2025 16:02:32 -0700 Subject: [PATCH 2/6] Apply suggestions from code review sidebar changes, header tweaks, few verbiage updates Co-authored-by: Ryan Levick Co-authored-by: itowlson Signed-off-by: MacKenzie Olson --- content/wasm-functions/using-cron-trigger.md | 8 ++++---- templates/functions_sidebar.hbs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/content/wasm-functions/using-cron-trigger.md b/content/wasm-functions/using-cron-trigger.md index 7fa61907e..84588c640 100644 --- a/content/wasm-functions/using-cron-trigger.md +++ b/content/wasm-functions/using-cron-trigger.md @@ -11,7 +11,7 @@ enable_shortcodes = true - [Deploy Spin Application to Fermyon Wasm Functions](#deploy-spin-application-to-fermyon-wasm-functions) - [Creating a Cron Job for Your Spin Application](#creating-a-cron-job-for-your-spin-application) - [Managing Cron Jobs](#managing-cron-jobs) -- [Delete Cron Job](#delete-cron-job) +- [Delete a Cron Job](#delete-cron-job) - [Next Steps](#next-steps) This tutorial guides you through the process of scheduling HTTP requests in a Spin application running on Fermyon Wasm Functions using cron jobs. The `spin aka crons` command allows applications to receive scheduled HTTP triggers without relying on external services. In this tutorial, you'll learn how to define and manage cron jobs using the `spin aka crons` command. @@ -34,9 +34,9 @@ Use Cases for Cron Jobs: * Log file rotation * Scheduled notifications -# Create Spin application +# Create a Spin Application -You must have a running Spin application on Fermyon Wasm Functions to apply the cron trigger to. We'll create a new Spin application for scheduling tasks using cron jobs using the `http-js` template: +You must have a running Spin application on Fermyon Wasm Functions to associate a cron job with. We'll create a new Spin application using the `http-js` template which we will then invoke on a schedule using a cron job: @@ -126,7 +126,7 @@ Hello from a cron component at 2025-04-02T03:16:14.212Z% # Creating a Cron Job for Your Spin Application -Now we will use the `spin aka crons` command to invoke the Spin app's HTTP endpoint at our desired interval. The syntax for this request follows standard crontab format. +Now we will use the `spin aka crons` command to invoke the Spin app's HTTP endpoint on our desired schedule. The syntax for this request follows standard crontab format. > `spin aka cron` supports single digits in each cron expression field and intervals in every position except the day of the week (e.g., `* */12 * * *` for every 12 hours). The smallest supported cron configuration is every 5 minutes (`*/5 * * * *`). Other syntax elements like comma-separated lists and ranges are not supported. Please feel free to[leave feedback](https://fibsu0jcu2g.typeform.com/to/G2u4tPcP) if your desired range is not supported. diff --git a/templates/functions_sidebar.hbs b/templates/functions_sidebar.hbs index 0a81acc5a..9ef87e4dc 100644 --- a/templates/functions_sidebar.hbs +++ b/templates/functions_sidebar.hbs @@ -22,7 +22,7 @@ Integrating with Property Manager Using the Key Value Store - Using the Key Value Store + Using Cron Jobs Querying PostgreSQL Querying MySQL (Linode) Building a Supabase Cache Proxy From e27738319c67c9865c3d60462d47386e1830e2ba Mon Sep 17 00:00:00 2001 From: macolso Date: Fri, 11 Apr 2025 13:33:38 -0700 Subject: [PATCH 3/6] updated example to give log cron events Signed-off-by: macolso --- content/wasm-functions/using-cron-jobs.md | 227 ++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 content/wasm-functions/using-cron-jobs.md diff --git a/content/wasm-functions/using-cron-jobs.md b/content/wasm-functions/using-cron-jobs.md new file mode 100644 index 000000000..c27ff69fd --- /dev/null +++ b/content/wasm-functions/using-cron-jobs.md @@ -0,0 +1,227 @@ +title = "Scheduling Tasks with Cron Jobs in Spin" +template = "functions_main" +date = "2025-03-25T00:00:01Z" +enable_shortcodes = true + +--- +- [Prerequisites](#prerequisites) +- [Introduction to Cron Jobs](#introduction-to-cron-jobs) + - [What Are Cron Jobs?](#what-are-cron-jobs) +- [Create a Spin Application](#create-a-spin-application) + - [Deploy Spin Application to Fermyon Wasm Functions](#deploy-spin-application-to-fermyon-wasm-functions) +- [Scheduling a Cron Job for Your Spin Application](#scheduling-a-cron-job-for-your-spin-application) +- [Managing Cron Jobs](#managing-cron-jobs) +- [Delete Cron Job](#delete-cron-job) +- [Next Steps](#next-steps) + +This tutorial guides you through the process of scheduling HTTP requests in a Spin application running on Fermyon Wasm Functions using cron jobs. The `spin aka crons` command allows applications to receive scheduled HTTP triggers without relying on external services. In this tutorial, you'll learn how to define and manage cron jobs using the `spin aka crons` command. + +# Prerequisites +Before proceeding, ensure you have the following: + +- Spin and the `spin aka` plugin installed on your machine ([Installation Guide](./quickstart.md)) +- Access to Fermyon Wasm Functions preview ([Sign Up Form](https://fibsu0jcu2g.typeform.com/fwf-preview)) + +# Introduction to Cron Jobs + +## What Are Cron Jobs? + +Cron jobs are scheduled tasks that run at specified intervals. They are commonly used for automating repetitive tasks such as data processing, report generation, and background maintenance. Other potential use cases include: + +* Automated data backups +* Periodic API polling +* Log file rotation +* Scheduled notifications + +# Create a Spin Application + +You must have a Spin application deployed to Fermyon Wasm Functions to associate a cron job. We'll create a new Spin application using the `http-js` template, which we will then invoke on a schedule using a cron job in later steps: + + + +```console +$ spin new -t http-js --accept-defaults hello-cron-job + +$ cd hello-cron-job + +$ npm install +``` + +We'll go ahead add a path that will be used our cron job in later steps: + +```toml +[[trigger.http]] +route = "/cron-me" +component = "hello-cron-job" +``` + +> Note that you can have multiple cron jobs per Spin application as long as the combination of schedule and path_and_query is unique. We will review how to apply those values later in the tutorial. + +Let's modify the response body to validate that our Spin application is running on a specific interval, and determine whether it was triggered by our cron job or via a direct request. If the request includes query parameters, we can infer that it came from the cron job, which we will set up in future steps. We’ll use this identifier to log the cron event. To apply these changes, navigate to the `hello-cron-job` directory, go to `src/index.js`, and add the following code snippet: + + + +```javascript +// For AutoRouter documentation refer to https://itty.dev/itty-router/routers/autorouter +import { AutoRouter } from 'itty-router'; + +// Initialize the router +let router = AutoRouter(); + +// Route ordering matters: +// - The first matching route is used +// - Routes can act as middleware if they don’t return a response +// - Unmatched routes return a 404 +router + .get("/cron-me", (request) => { + // Parse the request URL to access query parameters + const url = new URL(request.url); + + // Read the 'msg' query parameter, defaulting to an empty string if not provided + const msg = url.searchParams.get("msg"); + + // Capture current timestamp for logging and response + const now = new Date().toISOString(); + + // Log the trigger event, including the value of 'msg' + if (msg) { + console.log(`Hello, cron job triggered with msg: "${msg}" at ${now}`); + // Return a success response with a status 200 + return new Response( { + status: 200, + }); + } else { + // Return a direct ping response without logging + return new Response(`Hello! This is a direct ping at ${now}`, { + status: 200, + }); + } + }); + +// Attach the router to the fetch event +addEventListener('fetch', (event) => { + event.respondWith(router.fetch(event.request)); +}); +``` + +To build and run the application locally, run the following command: + + + +```console +spin build --up +``` + +Let's curl the application's endpoint to test if it is working as expected: + + + +```console +curl localhost:3000/cron-me +``` + + You should see a message returned along the lines of (_but with an accurate datetime at the time of following this tutoral_): + + + +```console +Hello! This is a direct ping at 2025-04-02T02:45:25.562Z +``` + +## Deploy Spin Application to Fermyon Wasm Functions + +Before scheduling our cron job, we deploy our Spin application to the Fermyon Wasm Functions platform. Deploy the application with the following command: + + + +```console +spin aka deploy +``` + +Upon successful deployment, you should receive a domain name that you can use to test the application: + + + +```console +curl https://ec8f3c23-b73d-4d51-aa69-aabd7ddc132a.aka.fermyon.tech/cron-me +Hello! This is a direct ping at 2025-04-02T03:16:14.212Z% +``` + +# Scheduling a Cron Job for Your Spin Application + +Now we will use the `spin aka crons` command to invoke the Spin app's HTTP endpoint on our desired schedule. The syntax for this request follows standard crontab format. + +> `spin aka crons` supports multiple digits in each cron expression field and intervals in every position (e.g., `* */12 * * *` for every 12 hours). Syntax elements like comma-separated lists and ranges are currently supported. Scheduling follows UTC and you may need to [convert your local time to UTC](https://www.worldtimebuddy.com/?pl=1&lid=100&h=100&hf=1) to ensure correct execution during daylight savings time. + +Let’s create a cron job that triggers your Spin application every 5 minutes. The `spin aka crons create` subcommand takes three arguments: + +* **Schedule:** How often the job runs, using standard cron syntax +* **Path and query:** The HTTP path (and optional query parameters) to invoke +* **Name:** The Spin applciaton to apply the cron job to + +In this example, we’ll schedule a job that hits the `/cron-me` path with a `msg` query parameter of "fwf" every 5 minutes for a Spin app named hello-cron-job. + + + +```console +spin aka crons create "*/5 * * * *" "/cron-me?msg=fwf" "hello-cron-job" +``` + +You should see output similar to: + + + +```console +Created cron which will next run at 2025-04-02 04:00:00 UTC +``` + +If we wait 5 minutes and check our application logs with the `spin aka logs` subcommand, we will see that our cron job invoked the application at the top of the hour as expected. + + + +```console +spin aka logs -a hello-cron-job +2025-04-02 04:00:00 [hello-cron-job] Hello, cron job triggered with msg: "fwf" at 2025-04-12T04:00:00Z +``` + +# Managing Cron Jobs + +You can view all of your running cron jobs with: + + + +```console +spin aka crons list +``` + + + +```console ++----------------+--------------+-------------------------+ +| Name | Schedule | Next Run | ++=========================================================+ +| hello-cron-job | */5 * * * * | 2025-04-02 04:00:00 UTC | ++----------------+--------------+-------------------------+ +``` + +# Delete Cron Job + +To delete a cron job, use: + + + +```console +spin aka crons delete hello-cron-job +``` + + + +```console +Deleted cron job 'hello-cron-job' with schedule '*/5 * * * *' +``` + +Your application will persist unless you explicitly run the `spin aka apps delete` command. + +# Next Steps + +* Visit [FAQ](faq.md) for frequently asked questions. \ No newline at end of file From 641100103b2b8b7fdfc94d378c1f4fbf481dfa73 Mon Sep 17 00:00:00 2001 From: macolso Date: Tue, 15 Apr 2025 14:13:22 -0700 Subject: [PATCH 4/6] simplified example and fixed typos, improved clarity of language Signed-off-by: macolso --- content/wasm-functions/using-cron-jobs.md | 102 +++++----- content/wasm-functions/using-cron-trigger.md | 191 ------------------- templates/functions_sidebar.hbs | 2 +- 3 files changed, 57 insertions(+), 238 deletions(-) delete mode 100644 content/wasm-functions/using-cron-trigger.md diff --git a/content/wasm-functions/using-cron-jobs.md b/content/wasm-functions/using-cron-jobs.md index c27ff69fd..d498ef177 100644 --- a/content/wasm-functions/using-cron-jobs.md +++ b/content/wasm-functions/using-cron-jobs.md @@ -55,9 +55,9 @@ route = "/cron-me" component = "hello-cron-job" ``` -> Note that you can have multiple cron jobs per Spin application as long as the combination of schedule and path_and_query is unique. We will review how to apply those values later in the tutorial. +> Note that you can have multiple cron jobs per Spin application as long as the combination of schedule and path_and_query is unique. We will review how to set those values later in the tutorial. -Let's modify the response body to validate that our Spin application is running on a specific interval, and determine whether it was triggered by our cron job or via a direct request. If the request includes query parameters, we can infer that it came from the cron job, which we will set up in future steps. We’ll use this identifier to log the cron event. To apply these changes, navigate to the `hello-cron-job` directory, go to `src/index.js`, and add the following code snippet: +Let’s update the event handler to confirm that our Spin application runs at the expected interval. To keep things simple, we’ll add a log statement that prints the message query value each time the application is triggered. This will help us verify that the cron job is working correctly. In a real-world scenario, you might use these values to query a database for stale records, call an API to sync data, or trigger a more complex workflow like sending a report or cleaning up expired sessions. To apply the changes, navigate to the `hello-cron-job` directory, open `src/index.js`, and add the following code snippet: @@ -68,35 +68,25 @@ import { AutoRouter } from 'itty-router'; // Initialize the router let router = AutoRouter(); -// Route ordering matters: -// - The first matching route is used -// - Routes can act as middleware if they don’t return a response -// - Unmatched routes return a 404 -router - .get("/cron-me", (request) => { - // Parse the request URL to access query parameters - const url = new URL(request.url); - - // Read the 'msg' query parameter, defaulting to an empty string if not provided - const msg = url.searchParams.get("msg"); - - // Capture current timestamp for logging and response - const now = new Date().toISOString(); - - // Log the trigger event, including the value of 'msg' - if (msg) { - console.log(`Hello, cron job triggered with msg: "${msg}" at ${now}`); - // Return a success response with a status 200 - return new Response( { - status: 200, - }); - } else { - // Return a direct ping response without logging - return new Response(`Hello! This is a direct ping at ${now}`, { - status: 200, - }); - } +// Define a route that responds to GET requests at /cron-me +router.get("/cron-me", (request) => { + // Parse the request URL to access query parameters + const url = new URL(request.url); + + // Read the 'msg' query parameter, defaulting to an empty string if not provided + const msg = url.searchParams.get("msg") || ""; + + // Capture the current timestamp + const now = new Date().toISOString(); + + // Log every time the route is triggered, including the message (if any) + console.log(`Cron job triggered at ${now} with msg: "${msg}"`); + + // Return a generic success response + return new Response("Cron job executed", { + status: 200, }); +}); // Attach the router to the fetch event addEventListener('fetch', (event) => { @@ -120,17 +110,17 @@ Let's curl the application's endpoint to test if it is working as expected: curl localhost:3000/cron-me ``` - You should see a message returned along the lines of (_but with an accurate datetime at the time of following this tutoral_): + You should see the following output in response: ```console -Hello! This is a direct ping at 2025-04-02T02:45:25.562Z +Cron job executed ``` ## Deploy Spin Application to Fermyon Wasm Functions -Before scheduling our cron job, we deploy our Spin application to the Fermyon Wasm Functions platform. Deploy the application with the following command: +Before scheduling our cron job, we must deploy our Spin application to the Fermyon Wasm Functions platform with the following command: @@ -138,33 +128,53 @@ Before scheduling our cron job, we deploy our Spin application to the Fermyon Wa spin aka deploy ``` -Upon successful deployment, you should receive a domain name that you can use to test the application: +Upon successful deployment, you should see output along the lines of: + + + +```console +App 'hello-cron-job' initialized successfully. +Waiting for application to be ready... ready + +Application URL: https://1064f8cc-4b83-4fb0-a550-ff51d8a85a18.aka.fermyon.tech/ + Routes: + - hello-cron-job: https://1064f8cc-4b83-4fb0-a550-ff51d8a85a18.aka.fermyon.tech/cron-me +``` + +You can use the domain name provided to you by Fermyon Wasm Functions to test that the Spin application is working as expected by curling the new endpoint: + + + +```console +curl https://1064f8cc-4b83-4fb0-a550-ff51d8a85a18.aka.fermyon.tech/cron-me +``` + +You should receive the same message as you did during local testing: ```console -curl https://ec8f3c23-b73d-4d51-aa69-aabd7ddc132a.aka.fermyon.tech/cron-me -Hello! This is a direct ping at 2025-04-02T03:16:14.212Z% +Cron job executed ``` # Scheduling a Cron Job for Your Spin Application -Now we will use the `spin aka crons` command to invoke the Spin app's HTTP endpoint on our desired schedule. The syntax for this request follows standard crontab format. +Now we’ll use the `spin aka crons` command to invoke the Spin application's HTTP endpoint on a scheduled basis. The schedule uses standard crontab syntax. -> `spin aka crons` supports multiple digits in each cron expression field and intervals in every position (e.g., `* */12 * * *` for every 12 hours). Syntax elements like comma-separated lists and ranges are currently supported. Scheduling follows UTC and you may need to [convert your local time to UTC](https://www.worldtimebuddy.com/?pl=1&lid=100&h=100&hf=1) to ensure correct execution during daylight savings time. +> `spin aka crons` supports multiple digits in each cron field, as well as intervals in any position (e.g., `* */12 * * *` to run every 12 hours). You can also use comma-separated lists and ranges. If your schedule includes a specific time of day, be sure to use UTC—you may need to [convert your local time to UTC](https://www.worldtimebuddy.com/?pl=1&lid=100&h=100&hf=1) to ensure correct execution. -Let’s create a cron job that triggers your Spin application every 5 minutes. The `spin aka crons create` subcommand takes three arguments: +Let’s create a cron job that triggers your Spin application every 5 minutes. The `spin aka crons` create subcommand takes three arguments: -* **Schedule:** How often the job runs, using standard cron syntax -* **Path and query:** The HTTP path (and optional query parameters) to invoke -* **Name:** The Spin applciaton to apply the cron job to +* **Schedule** – How often the job runs, in standard cron syntax +* **Path and query** – The HTTP path (and optional query parameters) to invoke +* **Name** – A name for your cron job (this will be associated with the Spin application in your current working directory) -In this example, we’ll schedule a job that hits the `/cron-me` path with a `msg` query parameter of "fwf" every 5 minutes for a Spin app named hello-cron-job. +In this example, we’ll schedule a job to hit the `/cron-me` path with a msg query parameter set to "fwf" every 5 minutes, for a Spin app named hello-cron-job. ```console -spin aka crons create "*/5 * * * *" "/cron-me?msg=fwf" "hello-cron-job" +spin aka crons create "*/5 * * * *" "/cron-me?msg=fwf" "cron-job-1" ``` You should see output similar to: @@ -175,13 +185,13 @@ You should see output similar to: Created cron which will next run at 2025-04-02 04:00:00 UTC ``` -If we wait 5 minutes and check our application logs with the `spin aka logs` subcommand, we will see that our cron job invoked the application at the top of the hour as expected. +If we wait 5 minutes and check our application logs with the `spin aka logs` subcommand, we will see that our cron job invoked the application every five minutes as expected. ```console spin aka logs -a hello-cron-job -2025-04-02 04:00:00 [hello-cron-job] Hello, cron job triggered with msg: "fwf" at 2025-04-12T04:00:00Z +2025-04-02 04:00:00 [hello-cron-job] Cron job triggered at 2025-04-12T04:00:00Z with msg: "fwf" ``` # Managing Cron Jobs diff --git a/content/wasm-functions/using-cron-trigger.md b/content/wasm-functions/using-cron-trigger.md deleted file mode 100644 index 84588c640..000000000 --- a/content/wasm-functions/using-cron-trigger.md +++ /dev/null @@ -1,191 +0,0 @@ -title = "Scheduling Tasks with Cron Jobs in Spin" -template = "functions_main" -date = "2025-03-25T00:00:01Z" -enable_shortcodes = true - ---- -- [Prerequisites](#prerequisites) -- [Introduction to Cron Jobs](#introduction-to-cron-jobs) - - [What Are Cron Jobs?](#what-are-cron-jobs) -- [Create Spin application](#create-spin-application) - - [Deploy Spin Application to Fermyon Wasm Functions](#deploy-spin-application-to-fermyon-wasm-functions) -- [Creating a Cron Job for Your Spin Application](#creating-a-cron-job-for-your-spin-application) -- [Managing Cron Jobs](#managing-cron-jobs) -- [Delete a Cron Job](#delete-cron-job) -- [Next Steps](#next-steps) - -This tutorial guides you through the process of scheduling HTTP requests in a Spin application running on Fermyon Wasm Functions using cron jobs. The `spin aka crons` command allows applications to receive scheduled HTTP triggers without relying on external services. In this tutorial, you'll learn how to define and manage cron jobs using the `spin aka crons` command. - -# Prerequisites -Before proceeding, ensure you have the following: - -- Spin and the `spin aka` plugin installed on your machine ([Installation Guide](./quickstart.md)) -- Access to Fermyon Wasm Functions preview ([Sign Up Form](https://fibsu0jcu2g.typeform.com/fwf-preview)) - -# Introduction to Cron Jobs - -## What Are Cron Jobs? - -Cron jobs are scheduled tasks that run at specified intervals. They are commonly used for automating repetitive tasks such as data processing, report generation, and background maintenance. - -Use Cases for Cron Jobs: -* Automated data backups -* Periodic API polling -* Log file rotation -* Scheduled notifications - -# Create a Spin Application - -You must have a running Spin application on Fermyon Wasm Functions to associate a cron job with. We'll create a new Spin application using the `http-js` template which we will then invoke on a schedule using a cron job: - - - -```console -$ spin new -t http-js --accept-defaults hello-cron-job - -$ cd hello-cron-job - -$ npm install -``` - -We'll go ahead add a specific path for our cron trigger in later steps: - -```toml -[[trigger.http]] -route = "/hello" -component = "hello-cron-job" -``` - -Let's modify the response body so we can validate that our application is running on a specific interval. To do so, navigate to `src/index.js` and add the following snippet of code: - - - -```JavaScript -// For AutoRouter documentation refer to https://itty.dev/itty-router/routers/autorouter -import { AutoRouter } from 'itty-router'; - -let router = AutoRouter(); - -// Route ordering matters, the first route that matches will be used -// Any route that does not return will be treated as a middleware -// Any unmatched route will return a 404 -router - .get("/hello", () => { - // Grab datetime - const now = new Date().toISOString(); - // Return response with time of invocation - return new Response(`Hello from a cron component at ${now}`, { status: 200 }); -}); - - -addEventListener('fetch', (event) => { - event.respondWith(router.fetch(event.request)); -}); -``` - -To test locally, run the following command: - - - -```console -spin build --up -``` - -If it is working as expected, you should see a message returned along the lines of (but with an accurate datetime): - - - -```console -curl localhost:3000 -``` - - - -```console -Hello from a cron component at 2025-03-31T21:45:25.562Z -``` - -## Deploy Spin Application to Fermyon Wasm Functions - -Before applying our cron trigger, we must have our Spin application running on the Fermyon Wasm Functions platform. Deploy the application with: - - - -```console -spin aka deploy -``` - -Upon successful deployment, you should receive a domain name that you can use to test the application: - - - -```console -curl https://ec8f3c23-b73d-4d51-aa69-aabd7ddc132a.aka.fermyon.tech/hello -Hello from a cron component at 2025-04-02T03:16:14.212Z% -``` - -# Creating a Cron Job for Your Spin Application - -Now we will use the `spin aka crons` command to invoke the Spin app's HTTP endpoint on our desired schedule. The syntax for this request follows standard crontab format. - -> `spin aka cron` supports single digits in each cron expression field and intervals in every position except the day of the week (e.g., `* */12 * * *` for every 12 hours). The smallest supported cron configuration is every 5 minutes (`*/5 * * * *`). Other syntax elements like comma-separated lists and ranges are not supported. Please feel free to[leave feedback](https://fibsu0jcu2g.typeform.com/to/G2u4tPcP) if your desired range is not supported. - -Let's create a cron job that runs every hour. Since scheduling is based on UTC, you may need to [convert your local time to UTC](https://www.worldtimebuddy.com/?pl=1&lid=100&h=100&hf=1) to ensure correct execution. - - - -```console -spin aka crons create "0 * * * *" "/hello" "hello-cron-job" -``` - -You should see output similar to: - - - -```console -Created cron which will next run at 2025-04-02 04:00:00 UTC -``` - -# Managing Cron Jobs - -You can view all of your running cron jobs with: - - - -```console -spin aka crons list -``` - - - -```console -+----------------+-----------+-------------------------+ -| Name | Schedule | Next Run | -+======================================================+ -| hello-cron-job | 0 * * * * | 2025-04-02 04:00:00 UTC | -+----------------+-----------+-------------------------+ -``` - -You can have multiple cron jobs per Spin application. - -# Delete Cron Job - -To delete a cron job, use: - - - -```console -spin aka crons delete hello-cron-job -``` - - - -```console -Deleted cron job 'hello-cron-job' with schedule '0 * * * *' -``` - -Your application will persist unless you explicitly run the `spin aka apps delete` command. - -# Next Steps - -* Visit [FAQ](faq.md) for frequently asked questions. \ No newline at end of file diff --git a/templates/functions_sidebar.hbs b/templates/functions_sidebar.hbs index 9ef87e4dc..5465f1c5a 100644 --- a/templates/functions_sidebar.hbs +++ b/templates/functions_sidebar.hbs @@ -22,7 +22,7 @@ Integrating with Property Manager Using the Key Value Store - Using Cron Jobs + Using Cron Jobs Querying PostgreSQL Querying MySQL (Linode) Building a Supabase Cache Proxy From 49ce264e8d4978c9b8e0e864915763fbb93438f0 Mon Sep 17 00:00:00 2001 From: macolso Date: Tue, 15 Apr 2025 20:59:47 -0700 Subject: [PATCH 5/6] simplifed example by removing path, bumped query and path requirements down, fixed cron typo Signed-off-by: macolso --- content/wasm-functions/using-cron-jobs.md | 57 +++++++++-------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/content/wasm-functions/using-cron-jobs.md b/content/wasm-functions/using-cron-jobs.md index d498ef177..3747ca2ab 100644 --- a/content/wasm-functions/using-cron-jobs.md +++ b/content/wasm-functions/using-cron-jobs.md @@ -40,24 +40,16 @@ You must have a Spin application deployed to Fermyon Wasm Functions to associate ```console -$ spin new -t http-js --accept-defaults hello-cron-job +$ spin new -t http-js --accept-defaults hello-world -$ cd hello-cron-job +$ cd hello-world $ npm install ``` -We'll go ahead add a path that will be used our cron job in later steps: +Let’s update the event handler to confirm that our Spin application runs at the expected interval. To keep things simple, we’ll add a log statement that prints the time the application is triggered. This will help us verify that the cron job is working correctly. In a real-world scenario, you might query a database for stale records, call an API to sync data, or trigger a more complex workflow like sending a report or cleaning up expired sessions. -```toml -[[trigger.http]] -route = "/cron-me" -component = "hello-cron-job" -``` - -> Note that you can have multiple cron jobs per Spin application as long as the combination of schedule and path_and_query is unique. We will review how to set those values later in the tutorial. - -Let’s update the event handler to confirm that our Spin application runs at the expected interval. To keep things simple, we’ll add a log statement that prints the message query value each time the application is triggered. This will help us verify that the cron job is working correctly. In a real-world scenario, you might use these values to query a database for stale records, call an API to sync data, or trigger a more complex workflow like sending a report or cleaning up expired sessions. To apply the changes, navigate to the `hello-cron-job` directory, open `src/index.js`, and add the following code snippet: +To apply the simple log changes, navigate to the `hello-world` directory, open `src/index.js`, and add the following code snippet: @@ -68,19 +60,16 @@ import { AutoRouter } from 'itty-router'; // Initialize the router let router = AutoRouter(); -// Define a route that responds to GET requests at /cron-me -router.get("/cron-me", (request) => { +// Define a route that responds to GET requests +router.get("/", (request) => { // Parse the request URL to access query parameters const url = new URL(request.url); - // Read the 'msg' query parameter, defaulting to an empty string if not provided - const msg = url.searchParams.get("msg") || ""; - // Capture the current timestamp const now = new Date().toISOString(); // Log every time the route is triggered, including the message (if any) - console.log(`Cron job triggered at ${now} with msg: "${msg}"`); + console.log(`Cron job triggered at ${now}"`); // Return a generic success response return new Response("Cron job executed", { @@ -107,7 +96,7 @@ Let's curl the application's endpoint to test if it is working as expected: ```console -curl localhost:3000/cron-me +curl localhost:3000 ``` You should see the following output in response: @@ -133,12 +122,10 @@ Upon successful deployment, you should see output along the lines of: ```console -App 'hello-cron-job' initialized successfully. +App 'hello-world' initialized successfully. Waiting for application to be ready... ready -Application URL: https://1064f8cc-4b83-4fb0-a550-ff51d8a85a18.aka.fermyon.tech/ - Routes: - - hello-cron-job: https://1064f8cc-4b83-4fb0-a550-ff51d8a85a18.aka.fermyon.tech/cron-me +Application URL: https://af30f3b0-ed52-4c5b-b2dd-b261945ff696.aka.fermyon.tech/ ``` You can use the domain name provided to you by Fermyon Wasm Functions to test that the Spin application is working as expected by curling the new endpoint: @@ -146,7 +133,7 @@ You can use the domain name provided to you by Fermyon Wasm Functions to test th ```console -curl https://1064f8cc-4b83-4fb0-a550-ff51d8a85a18.aka.fermyon.tech/cron-me +curl https://af30f3b0-ed52-4c5b-b2dd-b261945ff696.aka.fermyon.tech/ ``` You should receive the same message as you did during local testing: @@ -163,18 +150,20 @@ Now we’ll use the `spin aka crons` command to invoke the Spin application's HT > `spin aka crons` supports multiple digits in each cron field, as well as intervals in any position (e.g., `* */12 * * *` to run every 12 hours). You can also use comma-separated lists and ranges. If your schedule includes a specific time of day, be sure to use UTC—you may need to [convert your local time to UTC](https://www.worldtimebuddy.com/?pl=1&lid=100&h=100&hf=1) to ensure correct execution. -Let’s create a cron job that triggers your Spin application every 5 minutes. The `spin aka crons` create subcommand takes three arguments: +Let’s create a cron job that triggers your Spin application every 5 minutes with the `spin aka crons create` subcommand. The cron job you generate with this subcommand will be associated with the Spin application in your current working directory that you deployed to Fermyon Wasm Functions. The `spin aka crons create` subcommand takes three arguments: * **Schedule** – How often the job runs, in standard cron syntax -* **Path and query** – The HTTP path (and optional query parameters) to invoke -* **Name** – A name for your cron job (this will be associated with the Spin application in your current working directory) +* **Path and query** – The HTTP path and (optional) query parameters to invoke. +* **Name** – A name for your cron job + +> Note that you can have multiple cron jobs per Spin application as long as the combination of **schedule** and **path and query*** is unique. You might want multiple cron jobs in a single Spin application when different tasks need to run on separate schedules or require different logic. For example, you may want your Spin appliation to fetch different types of data, perform distinct maintenance routines, or sync with multiple external services independently. -In this example, we’ll schedule a job to hit the `/cron-me` path with a msg query parameter set to "fwf" every 5 minutes, for a Spin app named hello-cron-job. +In this example, we’ll schedule a job to hit the `/*` path with a msg query parameter set to "fwf" every 5 minutes, for a Spin app named hello-world. ```console -spin aka crons create "*/5 * * * *" "/cron-me?msg=fwf" "cron-job-1" +spin aka crons create "*/5 * * * *" "/*" "cron-job-1" ``` You should see output similar to: @@ -190,8 +179,8 @@ If we wait 5 minutes and check our application logs with the `spin aka logs` sub ```console -spin aka logs -a hello-cron-job -2025-04-02 04:00:00 [hello-cron-job] Cron job triggered at 2025-04-12T04:00:00Z with msg: "fwf" +spin aka logs -a hello-world +2025-04-02 04:00:00 [hello-world] Cron job triggered at 2025-04-12T04:00:00Z ``` # Managing Cron Jobs @@ -210,7 +199,7 @@ spin aka crons list +----------------+--------------+-------------------------+ | Name | Schedule | Next Run | +=========================================================+ -| hello-cron-job | */5 * * * * | 2025-04-02 04:00:00 UTC | +| cron-job-1 | */5 * * * * | 2025-04-02 04:00:00 UTC | +----------------+--------------+-------------------------+ ``` @@ -221,13 +210,13 @@ To delete a cron job, use: ```console -spin aka crons delete hello-cron-job +spin aka crons delete cron-job-1 ``` ```console -Deleted cron job 'hello-cron-job' with schedule '*/5 * * * *' +Deleted cron job 'cron-job-1' with schedule '*/5 * * * *' ``` Your application will persist unless you explicitly run the `spin aka apps delete` command. From 1ab1b8254db6eed711c43bce294076adf66406b8 Mon Sep 17 00:00:00 2001 From: MacKenzie Olson Date: Wed, 16 Apr 2025 15:33:49 -0700 Subject: [PATCH 6/6] Update content/wasm-functions/using-cron-jobs.md Co-authored-by: itowlson Signed-off-by: MacKenzie Olson --- content/wasm-functions/using-cron-jobs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/wasm-functions/using-cron-jobs.md b/content/wasm-functions/using-cron-jobs.md index 3747ca2ab..bfc6afc49 100644 --- a/content/wasm-functions/using-cron-jobs.md +++ b/content/wasm-functions/using-cron-jobs.md @@ -163,7 +163,7 @@ In this example, we’ll schedule a job to hit the `/*` path with a msg query pa ```console -spin aka crons create "*/5 * * * *" "/*" "cron-job-1" +spin aka crons create "*/5 * * * *" "/" "cron-job-1" ``` You should see output similar to: