docs: update scheduled jobs docs (#7905)

- Update scheduled jobs docs to support updated definition + remove coming soon notice
- Update scheduled jobs everywhere else they're used.
This commit is contained in:
Shahed Nasser authored and GitHub committed 2024-07-02 09:41:15 +00:00
1 parent 6cb28eedf7
commit 0aeba83a66
7 files changed
+103 -73

No files matched your search

@@ -0,0 +1,40 @@
export const metadata = {
title: `${pageNumber} Scheduled Jobs Number of Executions`,
}
# {metadata.title}
In this chapter, you'll learn how to set a limit on the number of times a scheduled job is executed.
## numberOfExecutions Option
The export configuration object of the scheduled job accepts an optional property `numberOfExecutions`. Its value is a number indicating how many times the scheduled job can be executed during the Medusa application's runtime.
For example:
export const highlights = [
["9", "numberOfExecutions", "The number of times the job should be executed."]
]
```ts highlights={highlights}
export default async function myCustomJob() {
console.log("I'll be executed three times only.")
}
export const config = {
name: "hello-world",
// execute every minute
schedule: "* * * * *",
numberOfExecutions: 3,
}
```
The above scheduled job has the `numberOfExecutions` configuration set to `3`.
So, it'll only execute 3 times, each every minute, then it won't be executed anymore.
<Note>
If you restart the Medusa application, the scheduled job will be executed again until reaching the number of executions specified.
</Note>
@@ -6,12 +6,6 @@ export const metadata = {
In this chapter, you’ll learn about scheduled jobs and how to use them. In this chapter, you’ll learn about scheduled jobs and how to use them.
<Note type="soon">
Scheduled jobs are coming soon.
</Note>
## What is a Scheduled Job? ## What is a Scheduled Job?
A scheduled job is a function executed at a specified interval of time in the background of your Medusa application. It’s like a cron job that runs during the application's runtime. A scheduled job is a function executed at a specified interval of time in the background of your Medusa application. It’s like a cron job that runs during the application's runtime.
@@ -22,30 +16,23 @@ For example, you can synchronize your inventory with an Enterprise Resource Plan
## How to Create a Scheduled Job? ## How to Create a Scheduled Job?
<Note type="check">
- [Redis](https://redis.io/) is installed and Redis server is running.
</Note>
A scheduled job is created in a TypeScript or JavaScript file under the `src/jobs` directory. A scheduled job is created in a TypeScript or JavaScript file under the `src/jobs` directory.
For example, create the file `src/jobs/hello-world.ts` with the following content: For example, create the file `src/jobs/hello-world.ts` with the following content:
```ts title="src/jobs/hello-world.ts" ```ts title="src/jobs/hello-world.ts"
import { ScheduledJobConfig } from "@medusajs/medusa"
// the scheduled-job function // the scheduled-job function
export default function () { export default function () {
console.log("Time to say hello world!") console.log("Time to say hello world!")
} }
// the job's configurations // the job's configurations
export const config: ScheduledJobConfig = { export const config = {
name: "hello-world", name: "hello-world",
// execute every minute // execute every minute
schedule: "* * * * *", schedule: "* * * * *",
} }
``` ```
A scheduled job file must export: A scheduled job file must export:
@@ -59,20 +46,7 @@ This scheduled job executes every minute and logs into the terminal `Time to say
### Test Scheduled Jobs ### Test Scheduled Jobs
To test out your scheduled job: To test out your scheduled job, start the Medusa application:
1. Uncomment the following line in the `medusa-config.js` file:
```js title="medusa-config.js"
module.exports = defineConfig({
projectConfig: {
redisUrl: REDIS_URL,
// ...
},
})
```
2. Start the Medusa application:
```bash npm2yarn ```bash npm2yarn
npm run dev npm run dev
@@ -81,12 +55,9 @@ npm run dev
After a minute, the following message will be logged to the terminal: After a minute, the following message will be logged to the terminal:
```bash ```bash
info: Processing scheduled job: hello-world
Time to say hello world! Time to say hello world!
``` ```
The first line indicates that the application is executing the scheduled job. The second line is the text logged by the scheduled job.
--- ---
## When to Use Scheduled Jobs ## When to Use Scheduled Jobs
@@ -115,32 +86,31 @@ The scheduled job function receives an object parameter that has a `container` p
For example: For example:
export const highlights = [ export const highlights = [
["12", "resolve", "Resolve the Product Module's main service."], ["11", "resolve", "Resolve the Product Module's main service."],
["12", "ModuleRegistrationName.PRODUCT", "The resource registration name imported from `@medusajs/modules-sdk`."] ["11", "ModuleRegistrationName.PRODUCT", "The resource registration name imported from `@medusajs/modules-sdk`."]
] ]
```ts title="src/jobs/hello-world.ts" highlights={highlights} ```ts title="src/jobs/hello-world.ts" highlights={highlights}
import { import {
ScheduledJobArgs, IProductModuleService,
ScheduledJobConfig, MedusaContainer,
} from "@medusajs/medusa" } from "@medusajs/types"
import { IProductModuleService } from "@medusajs/types" import { ModuleRegistrationName } from "@medusajs/utils"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
export default async function ({ export default async function myCustomJob(
container, container: MedusaContainer
}: ScheduledJobArgs) { ) {
const productModuleService: IProductModuleService = const productModuleService: IProductModuleService =
container.resolve(ModuleRegistrationName.PRODUCT) container.resolve(ModuleRegistrationName.PRODUCT)
const [, count] = await productModuleService.listAndCount() const [, count] = await productModuleService.listAndCountProducts()
console.log( console.log(
`Time to check products! You have ${count} product(s)` `Time to check products! You have ${count} product(s)`
) )
} }
export const config: ScheduledJobConfig = { export const config = {
name: "hello-world", name: "hello-world",
// execute every minute // execute every minute
schedule: "* * * * *", schedule: "* * * * *",
+7 -10
View File
@@ -156,16 +156,13 @@ To execute the workflow, invoke it passing the Medusa container as a parameter.
</CodeTab> </CodeTab>
<CodeTab label="Scheduled Job" value="scheduled-job"> <CodeTab label="Scheduled Job" value="scheduled-job">
```ts title="src/jobs/message-daily.ts" highlights={[["10"], ["11"], ["12"], ["13"], ["14"], ["15"]]} ```ts title="src/jobs/message-daily.ts" highlights={[["7"], ["8"], ["9"], ["10"], ["11"], ["12"]]}
import { import { MedusaContainer } from "@medusajs/types"
type ScheduledJobConfig,
type ScheduledJobArgs,
} from "@medusajs/medusa"
import myWorkflow from "../workflows/hello-world" import myWorkflow from "../workflows/hello-world"
export default async function handler({ export default async function myCustomJob(
container, container: MedusaContainer
}: ScheduledJobArgs) { ) {
const { result } = await myWorkflow(container) const { result } = await myWorkflow(container)
.run({ .run({
input: { input: {
@@ -176,10 +173,10 @@ To execute the workflow, invoke it passing the Medusa container as a parameter.
console.log(result.message) console.log(result.message)
} }
export const config: ScheduledJobConfig = { export const config = {
name: "run-once-a-day", name: "run-once-a-day",
schedule: `0 0 * * *`, schedule: `0 0 * * *`,
} };
``` ```
</CodeTab> </CodeTab>
+9
View File
@@ -179,6 +179,15 @@ export const sidebar = sidebarAttachHrefCommonOptions(
}, },
], ],
}, },
{
title: "Scheduled Jobs",
children: [
{
path: "/advanced-development/scheduled-jobs/execution-number",
title: "Execution Number",
},
],
},
{ {
title: "Workflows", title: "Workflows",
children: [ children: [
@@ -163,7 +163,7 @@ In this document, you’ll find common examples of how you can use the Pricing M
} from "@medusajs/pricing" } from "@medusajs/pricing"
export async function GET( export async function GET(
request: Request, request: Request
) { ) {
const pricingModuleService = await initializePricingModule() const pricingModuleService = await initializePricingModule()
@@ -381,7 +381,7 @@ In this document, you’ll find common examples of how you can use the Pricing M
} from "@medusajs/pricing" } from "@medusajs/pricing"
export async function GET( export async function GET(
request: Request, request: Request
) { ) {
const pricingModuleService = await initializePricingModule() const pricingModuleService = await initializePricingModule()
@@ -436,19 +436,13 @@ Medusa also provides Notification Module Providers that integrate with third-par
As your commerce store grows, you'll likely need to synchronize data across different systems. For example, you need to synchronize data with an ERP system or a data warehouse. As your commerce store grows, you'll likely need to synchronize data across different systems. For example, you need to synchronize data with an ERP system or a data warehouse.
You can do that by: To implement that:
- Creating a workflow that implements the synchronization steps, along with retry and rollback logic. - Create a workflow that implements the synchronization steps, along with retry and rollback logic.
- Creating a scheduled job that executes the workflow automatically at the specified time pattern. - Create a scheduled job that executes the workflow automatically at the specified time pattern.
<Note type="soon">
Scheduled jobs are coming soon.
</Note>
<Card <Card
href="#" href="!docs!/basics/scheduled-jobs"
title="Create a Scheduled Job" title="Create a Scheduled Job"
text="Learn how to create a scheduled job in Medusa." text="Learn how to create a scheduled job in Medusa."
startIcon={<AcademicCapSolid />} startIcon={<AcademicCapSolid />}
@@ -633,6 +627,33 @@ export const syncProductsWorkflowHighlight = [
3. Sync the retrieved products with a third-party service. It's assumed that the connection to the third-party service is implemented within a custom module's main service. 3. Sync the retrieved products with a third-party service. It's assumed that the connection to the third-party service is implemented within a custom module's main service.
4. Update the last sync date of the store to the current date. 4. Update the last sync date of the store to the current date.
Then, create a scheduled job at `src/jobs/sync-products.ts` that executes the workflow at the specified interval:
```ts
import { MedusaContainer } from "@medusajs/types"
import {
syncProductsWorkflow,
} from "../workflows/sync-products"
export default async function syncProductsJob(
container: MedusaContainer
) {
await syncProductsWorkflow(container)
.run({
input: {
name: "John",
},
})
}
export const config = {
name: "sync-products",
// execute every minute
schedule: "0 0 * * *",
numberOfExecutions: 3,
}
```
</Details> </Details>
--- ---
@@ -842,12 +863,6 @@ To do that, create a subscriber that listens to the `product.created`, and send
You can also create a scheduled job that checks whether the number of new products has exceeded a set threshold, then sends out the newsletter. You can also create a scheduled job that checks whether the number of new products has exceeded a set threshold, then sends out the newsletter.
<Note type="soon">
Scheduled jobs are coming soon.
</Note>
<CardList items={[ <CardList items={[
{ {
href: "!docs!/basics/events-and-subscribers", href: "!docs!/basics/events-and-subscribers",
@@ -80,7 +80,6 @@ Implementing the logic depends on your use case, but you'll mainly implement the
<Note type="soon"> <Note type="soon">
- The `order.placed` event isn't emitted yet. - The `order.placed` event isn't emitted yet.
- Scheduled jobs are coming soon.
</Note> </Note>