medusajs / medusa

The world's most flexible commerce platform.
https://medusajs.com
MIT License
25.92k stars 2.6k forks source link

Scheduled Jobs fail when @medusajs/workflow-engine-redis is used #8422

Closed letalumil closed 3 months ago

letalumil commented 3 months ago

Bug report

Describe the bug

I just created a new medusa v2.0.3 store to try it out. I created a simple Scheduled Job that just logs messages to the console. With @medusajs/workflow-engine-inmemory the Job worked fine. After I installed and configured @medusajs/workflow-engine-redis@^0.0.5-preview-20240802180540 the Job stopped working, with the error in the console:

info:    Connection to Redis in module 'event-bus-redis' established
info:    Connection to Redis in module 'cache-redis' established
info:    Connection to Redis in module 'workflow-engine-redis' established
info:    Connection to Redis PubSub in module 'workflow-engine-redis' established
info:    No job to load from /medusa/medusa-v2-store/node_modules/@medusajs/medusa/dist/jobs. skipped.
TypeError: Cannot read properties of undefined (reading 'schedule')
    at WorkflowScheduler.scheduleWorkflow (/medusa/medusa-v2-store/node_modules/@medusajs/orchestration/src/workflow/scheduler.ts:32:37)
    at Function.register (/medusa/medusa-v2-store/node_modules/@medusajs/orchestration/src/workflow/workflow-manager.ts:139:22)
    at createWorkflow (/medusa/medusa-v2-store/node_modules/@medusajs/workflows-sdk/src/utils/composer/create-workflow.ts:100:21)
    at registerJob (/medusa/medusa-v2-store/node_modules/@medusajs/framework/dist/jobs/job-loader.js:96:44)
    at Array.map (<anonymous>)
    at JobLoader.load (/medusa/medusa-v2-store/node_modules/@medusajs/framework/dist/jobs/job-loader.js:138:23)
    at async jobsLoader (/medusa/medusa-v2-store/node_modules/@medusajs/medusa/src/loaders/index.ts:63:3)
    at async loadEntrypoints (/medusa/medusa-v2-store/node_modules/@medusajs/medusa/src/loaders/index.ts:78:5)
    at async exports.default (/medusa/medusa-v2-store/node_modules/@medusajs/medusa/src/loaders/index.ts:158:31)
    at async start (/medusa/medusa-v2-store/node_modules/@medusajs/medusa/src/commands/start.ts:22:28)
✔ Server is ready on port: 9000 – 7ms

System information

Medusa version (including plugins): Node.js version: v20.12.0 Database: PostgreSQL 15.3 Redis: 7.0.11 Operating system: macOS 14.5

Expected behavior

The Scheduled Job should work with @medusajs/workflow-engine-redis.

Code snippets

medusa-config.js:

module.exports = defineConfig({
  projectConfig: {
    databaseUrl: process.env.DATABASE_URL,
    redisUrl: process.env.REDIS_URL,
    http: {
      storeCors: process.env.STORE_CORS,
      adminCors: process.env.ADMIN_CORS,
      authCors: process.env.AUTH_CORS,
      jwtSecret: process.env.JWT_SECRET || "supersecret",
      cookieSecret: process.env.COOKIE_SECRET || "supersecret",
    },
  },
  modules: {
    [Modules.CACHE]: {
      resolve: "@medusajs/cache-redis",
      options: {
        redisUrl: process.env.REDIS_URL,
      },
    },
    [Modules.EVENT_BUS]: {
      resolve: "@medusajs/event-bus-redis",
      options: {
        redisUrl: process.env.REDIS_URL,
      },
    },
    [Modules.WORKFLOW_ENGINE]: {
      resolve: "@medusajs/workflow-engine-redis",
      options: {
        redis: {
          url: process.env.REDIS_URL,
        },
      },
    },
  },
});
sradevski commented 3 months ago

@letalumil can you please share your scheduled job definition? Also, can you please upgrade to the latest preview version?

I just tried on the latest preview version and the job is working as expected with the redis engine.

letalumil commented 3 months ago

@sradevski thanks for responding to me about my problem.

I just tried from scratch, created a new project running npx create-medusa-app@preview. The create-medusa-app@1.2.9-preview-20240805180532 was used to create a project.

After the project was created, I ran yarn add @medusajs/workflow-engine-redis@preview, which installed @medusajs/workflow-engine-redis@0.0.5-preview-20240805180532.

In medusa-config.js I added the following section:

  modules: {
    [Modules.WORKFLOW_ENGINE]: {
      resolve: "@medusajs/workflow-engine-redis",
      options: {
        redis: {
          url: process.env.REDIS_URL,
        },
      },
    },
  },

And then created a src/jobs/job.ts file with the following content:

export default async function myCustomJob() {
  console.log("Hello from my custom job");
}

export const config = {
  name: "test-job",
  schedule: "* * * * *",
};

The start the whole thing with yarn dev. Unfortunately, the result is still the same.

~/Developer/medusa/medusa-v2-store-test ❯ yarn dev                                                                                           ✘ INT 4s  20.12.0 19:52:37
yarn run v1.22.22
$ medusa develop
info:    Watching filesystem to reload dev server on file change
redisUrl not found. A fake redis instance will be used.
info:    No link to load from /Users/letalumil/Developer/medusa/medusa-v2-store-test/src/links. skipped.
warn:    Local Event Bus installed. This is not recommended for production.
info:    Connection to Redis in module 'workflow-engine-redis' established
info:    Connection to Redis PubSub in module 'workflow-engine-redis' established
info:    No job to load from /Users/letalumil/Developer/medusa/medusa-v2-store-test/node_modules/@medusajs/medusa/dist/jobs. skipped.
TypeError: Cannot read properties of undefined (reading 'schedule')
    at WorkflowScheduler.scheduleWorkflow (/Users/letalumil/Developer/medusa/medusa-v2-store-test/node_modules/@medusajs/orchestration/src/workflow/scheduler.ts:32:37)
    at Function.register (/Users/letalumil/Developer/medusa/medusa-v2-store-test/node_modules/@medusajs/orchestration/src/workflow/workflow-manager.ts:139:22)
    at createWorkflow (/Users/letalumil/Developer/medusa/medusa-v2-store-test/node_modules/@medusajs/workflows-sdk/src/utils/composer/create-workflow.ts:100:21)
    at registerJob (/Users/letalumil/Developer/medusa/medusa-v2-store-test/node_modules/@medusajs/framework/dist/jobs/job-loader.js:96:44)
    at Array.map (<anonymous>)
    at JobLoader.load (/Users/letalumil/Developer/medusa/medusa-v2-store-test/node_modules/@medusajs/framework/dist/jobs/job-loader.js:138:23)
    at async jobsLoader (/Users/letalumil/Developer/medusa/medusa-v2-store-test/node_modules/@medusajs/medusa/src/loaders/index.ts:63:3)
    at async loadEntrypoints (/Users/letalumil/Developer/medusa/medusa-v2-store-test/node_modules/@medusajs/medusa/src/loaders/index.ts:78:5)
    at async exports.default (/Users/letalumil/Developer/medusa/medusa-v2-store-test/node_modules/@medusajs/medusa/src/loaders/index.ts:158:31)
    at async start (/Users/letalumil/Developer/medusa/medusa-v2-store-test/node_modules/@medusajs/medusa/src/commands/start.ts:22:28)
✔ Server is ready on port: 9000 – 6ms

Please see the medusa package versions below, if it helps.

~/Developer/medusa/medusa-v2-store-test ❯ yarn list --pattern "@medusa"                                                                                20.12.0 20:02:46
yarn list v1.22.22
├─ @medusajs/admin-sdk@0.0.2-preview-20240805150447
├─ @medusajs/admin-shared@0.0.2-preview-20240805150447
├─ @medusajs/admin-vite-plugin@0.0.2-preview-20240805150447
├─ @medusajs/api-key@0.1.3-preview-20240805150447
├─ @medusajs/auth-emailpass@0.0.2-preview-20240805150447
├─ @medusajs/auth@0.0.4-preview-20240805150447
├─ @medusajs/cache-inmemory@1.8.11-preview-20240805150447
├─ @medusajs/cart@0.0.4-preview-20240805150447
├─ @medusajs/core-flows@0.0.10-preview-20240805150447
├─ @medusajs/currency@0.1.3-preview-20240805150447
├─ @medusajs/customer@0.0.4-preview-20240805150447
├─ @medusajs/dashboard@0.0.2-preview-20240805150447
├─ @medusajs/event-bus-local@1.9.9-preview-20240805150447
├─ @medusajs/file-local-next@0.0.3-preview-20240805150447
├─ @medusajs/file@0.0.2-preview-20240805150447
├─ @medusajs/framework@0.0.2-preview-20240805150447
│  └─ @medusajs/medusa-cli@1.3.23-preview-20240805150447
├─ @medusajs/fulfillment-manual@0.0.3-preview-20240805150447
├─ @medusajs/fulfillment@0.1.3-preview-20240805150447
├─ @medusajs/icons@1.2.2-preview-20240805150447
├─ @medusajs/inventory-next@0.0.4-preview-20240805150447
├─ @medusajs/js-sdk@0.0.2-preview-20240805150447
├─ @medusajs/link-modules@0.2.12-preview-20240805150447
├─ @medusajs/medusa-cli@1.3.23-preview-20240805150447
├─ @medusajs/medusa@1.20.6-preview-20240805150447
│  └─ @medusajs/medusa-cli@1.3.23-preview-20240805150447
├─ @medusajs/modules-sdk@1.13.0-preview-20240805150447
├─ @medusajs/notification-local@0.0.2-preview-20240805150447
├─ @medusajs/notification@0.1.3-preview-20240805150447
├─ @medusajs/orchestration@0.5.8-preview-20240805150447
├─ @medusajs/order@0.1.3-preview-20240805150447
├─ @medusajs/payment@0.0.4-preview-20240805150447
├─ @medusajs/pricing@0.1.13-preview-20240805150447
├─ @medusajs/product@0.3.13-preview-20240805150447
├─ @medusajs/promotion@0.0.5-preview-20240805150447
├─ @medusajs/region@0.1.2-preview-20240805150447
├─ @medusajs/sales-channel@0.1.2-preview-20240805150447
├─ @medusajs/stock-location-next@0.0.4-preview-20240805150447
├─ @medusajs/store@0.1.2-preview-20240805150447
├─ @medusajs/tax@0.1.2-preview-20240805150447
├─ @medusajs/types@1.12.0-preview-20240805150447
├─ @medusajs/ui@3.0.1-preview-20240805150447
├─ @medusajs/user@0.0.4-preview-20240805150447
├─ @medusajs/utils@1.12.0-preview-20240805150447
├─ @medusajs/workflow-engine-inmemory@0.0.5-preview-20240805150447
├─ @medusajs/workflow-engine-redis@0.0.5-preview-20240805180532
│  ├─ @medusajs/modules-sdk@1.13.0-preview-20240805180532
│  ├─ @medusajs/orchestration@0.5.8-preview-20240805180532
│  ├─ @medusajs/types@1.12.0-preview-20240805180532
│  ├─ @medusajs/utils@1.12.0-preview-20240805180532
│  └─ @medusajs/workflows-sdk@0.1.7-preview-20240805180532
└─ @medusajs/workflows-sdk@0.1.7-preview-20240805150447
sradevski commented 3 months ago

@letalumil ok I managed to reproduce it, it is something to do with how the redis storage is registered, I'll keep you updated.

sradevski commented 3 months ago

@letalumil the issue was that you ended up having two different versions of a package that is supposed to be a singleton, which is why I didn't manage to reproduce it the first time (I got lucky and ended up with a single version). It will be fixed in the linked PR

letalumil commented 3 months ago

@sradevski great news, thank you for fixing the thing :)

joekendal commented 1 month ago

I'm getting this error just by following the v2.0 docs https://docs.medusajs.com/v2/basics/scheduled-jobs:

src/jobs/hello-world.ts

import {
  IProductModuleService,
  MedusaContainer,
} from "@medusajs/types"
import { Modules } from "@medusajs/utils"

export default async function myCustomJob(
  container: MedusaContainer
) {
  const productModuleService: IProductModuleService =
    container.resolve(Modules.PRODUCT)

  const [, count] = await productModuleService.listAndCountProducts()

  console.log(
    `Time to check products! You have ${count} product(s)`
  )
}

export const config = {
  name: "every-minute-message",
  // execute every minute
  schedule: "* * * * *",
}

yarn dev

yarn run v1.22.19
$ medusa develop
info:    Watching filesystem to reload dev server on file change
info:    OTEL registered
info:    Connection to Redis in module 'event-bus-redis' established
info:    Connection to Redis in module 'cache-redis' established
info:    Connection to Redis in module 'workflow-engine-redis' established
[HELLO MODULE] Just started the Medusa application!
info:    Connection to Redis PubSub in module 'workflow-engine-redis' established
info:    No job to load from ./node_modules/@medusajs/medusa/dist/jobs. skipped.
info:    Geneated modules types
✔ Server is ready on port: 9000 – 6ms
error:   Scheduled job every-minute-message failed with error: handler is not a function
error:   job-every-minute-message:every-minute-message-as-step:invoke - handler is not a function
TypeError: handler is not a function

yarn.lock

...
"@medusajs/medusa@preview":
  version "1.20.6-preview-20240925143312"
  resolved "https://registry.yarnpkg.com/@medusajs/medusa/-/medusa-1.20.6-preview-20240925143312.tgz#f6b44e2b19491519c1c7ce4b0017a48d5de4dd3c"
...