Giter VIP home page Giter VIP logo

pulse's Introduction

project-logo

PULSE

The modern MongoDB-powered job scheduler library for Node.js

license last-commit repo-top-language repo-language-count


Documentation | Website

Table of Contents

Overview

Pulse is a new fork of the Agenda project, created as the original project is no longer actively maintained. Positioned as a vital solution in the Node.js ecosystem for job scheduling, the hiatus of Agenda prompted the creation of Pulse. Utilizing MongoDB, Pulse introduces advanced functionalities, improved scalability, and contemporary features to address today’s complex scheduling challenges.


Related Projects

  • pulsecron - Event-driven task scheduling management infrastructure
  • nestjs-pulse - official NestJS module for Pulse.



Unique Features in Pulse

  • Latest MongoDB Driver Support: Pulse is fully compatible with the latest MongoDB driver, ensuring users can take advantage of the most current database features and enhancements.
  • Resume Incomplete Tasks After System Restart: When the system restarts, Pulse resumes incomplete tasks that were in progress or queued for execution, providing seamless continuation without manual intervention.
  • Retry Failed Tasks: Pulse offers retry mechanisms using exponential and fixed backoff strategies with configurable attempts, ensuring efficient retries of failed tasks without overwhelming the system.
  • Continuous Maintenance: As an open-source project actively used in a production service, Pulse is consistently maintained and improved, providing users with reliable updates and support.
  • Extensive Documentation: Provides detailed guides and examples for a quick and easy start.



Repository Structure

└── pulse/
    ├── LICENSE
    ├── README.md
    ├── es.js
    ├── examples
    │   └── concurrency.ts
    ├── package-lock.json
    ├── package.json
    ├── src
    │   ├── cjs.ts
    │   ├── index.ts
    │   ├── job
    │   ├── pulse
    │   └── utils
    ├── tsconfig.eslint.json
    └── tsconfig.json



Modules

src.pulse
File Summary
has-mongo-protocol.ts HasMongoProtocol establishes a function that evaluates if a given URL string contains a valid MongoDB connection protocol, contributing to the repositorys ability to handle and verify database connections.
default-concurrency.ts Sets the default concurrency for each job within the Pulse open-source project by modifying the internal state. It contributes to the task scheduling and management functionalities in the project.
name.ts Sets the name of a queue within the Pulse object in the parent repositorys architecture. It utilizes debugging for traceability and maintains the flow architecture by returning the Pulse instance after the name assignment.
drain.ts Drain.ts serves a crucial role in the Pulse module, enabling the cancellation of ongoing job processes. It ensures that all running jobs get completed before terminating the processing interval, promoting an efficient and orderly execution flow in the application.
enable.ts Enables specific jobs within the Pulse module by toggling the disabled flag to false. Utilizes MongoDB queries to precisely select matching jobs, aspiring to enhance the flexibility and robustness of job execution. Returns the count of jobs successfully enabled, aiding in operational tracking.
schedule.ts Schedule.ts within the Pulse directory facilitates job scheduling for specific timings. Through this module, users can assign an array of job names to be executed at a specified time, along with associated data. Multiple jobs can be created at once, enhancing the efficiency of task management in the repository.
default-lock-lifetime.ts Establishes the default lock lifetime in a Pulse application. It allows setting the default lock time in milliseconds, providing flexibility in managing task execution timelines. This is a critical feature for handling concurrency control in Pulses job processing system.
db-init.ts Establishes and initializes the database collection for job management in the Pulse open-source project. It also includes optional index creation functionality, providing efficient job searching within the database. Notifiers for success or errors make the process transparent and manageable.
process-every.ts ProcessEvery sets a default interval for a Pulse objects processing time. It leverages human-readable time intervals to determine the frequency of certain operations within the pulse directory of the repository. This function returns the updated Pulse object.
disable.ts Disables selected jobs in the Pulse application by applying a MongoDB filter query. The function returns the number of successfully disabled job instances, providing enhanced control over task execution.
jobs.ts Within the Pulse repository, the jobs.ts script from the src/pulse directory performs a crucial task. It retrieves all jobs matching a certain query from a MongoDB collection, with options for sorting, limiting and skipping results, transforming these into job objects before returning.
start.ts Start.ts initializes job processing for the Pulse module. It validates system readiness before periodically processing tasks using the processJobs method from the utils directory. The method ensures job execution regularity and guarantees uninterrupted operation, provided a database is set beforehand.
every.ts Within the pulse directory, every.ts establishes a regular job execution framework. It enables job scheduling at specified intervals, handling singular and multiple job names. Pertinent debugging information for scheduled job processes is also provided by this module.
max-concurrency.ts MaxConcurrency controls job execution in the Pulse system by globally setting the maximum concurrency value, thereby optimizing task management. It directly interacts with the core Pulse framework, ensuring that job execution does not exceed the defined threshold, enhancing overall process efficiency.
purge.ts Purge.ts, within the pulse subdirectory, provides functionality to remove all jobs from the queue in the Pulse application. It exports an asynchronous function that cancels undefined jobs, ensuring only defined jobs remain. The function's outcome is confirmed with success or failure notifications.
now.ts Establishes a function within the Pulse module, designed to create a job task instantly. This function, named now, accepts job details, schedules it for the current time, saves the job into the system, and handles potential creation errors.
default-lock-limit.ts Defines the maximum number of locks per job type in the Pulse system. It establishes a default limit, with each instance adjustable per user needs. The limit optimizes concurrent task handling, enhancing overall application performance.
stop.ts Stop.ts within the Pulse sub-directory is responsible for terminating the process of job execution. It achieves this by unlocking jobs that were locked for processing, allowing them to be re-run or accessed, and by clearing the job execution interval, effectively stopping further job processing.
database.ts Database.ts, located in the src/pulse directory, establishes a connection to a specified MongoDB server. It features the flexibility to use an existing MongoDB connection, customize collection names, and handle connection errors. Ultimately, this file integrates MongoDB into the broader Pulse architecture.
sort.ts Sort.ts orchestrates the sorting functionality within the Pulse component, allowing users to customize their queries for job searches. It primarily manages the rules for prioritizing and scheduling jobs, with the default being jobs sorted by their next run time and priority.
mongo.ts Mongo.ts integrates MongoDB with the Pulse application, enabling the establishment of database connections. It provides a method to inject MongoClient instance, specify the collection, and handle database initialization errors through callbacks.
cancel.ts Cancel.ts facilitates the termination of specific Pulse jobs based on a provided MongoDB query, effectively removing them from the database. These cancellations can be initiated by the client code, the Pulse.purge() function, or the Job.remove() function.
index.ts Pulse, the heart of the repository, manages a queue of jobs in a MongoDB collection. This task scheduling system facilitates job creation, scheduling, locking, and execution, handling concurrency defaults, lock limits, and durations. Moreover, it supports optional configuration and customization parameters.
define.ts Defines job parameters and execution procedures in the Pulse library. Users can configure concurrency, locking, priority, lifetime, and result persistence for a named job. Job definitions are stored and debugged for future execution within the Pulse system.
create.ts Creates new jobs within the Pulse module of the repository. This piece of code initializes these jobs with given names and data, also setting specific attributes such as priority and whether to save results based on predefined definitions.
find-and-lock-next-job.ts Unlocks and processes queued jobs within the Pulse repository. In the find-and-lock-next-job file, the function identifies a specific job based on its name, locks it for execution, and returns the job status. This operation ensures efficient management of tasks within the system.
job-processing-queue.ts JobProcessingQueue, as part of the larger Pulse repository, manages job processing through an internal queue. It offers capabilities like job insertion in a specific order, popping jobs without concurrency checks, and identifying the next job eligible for processing whose execution isnt blocked by concurrency.
lock-limit.ts LockLimit sets a global upper limit on the number of jobs that can be simultaneously locked within the Pulse system, ensuring efficient task execution without resource overstretching. Its essential for maintaining concurrency control in the broader repository architecture.
close.ts Pulse/close.ts secures the main functionality of closing database connections within the Pulse project. It incorporates a provision for forcefully closing connections and handles exceptions that might arise during this process. The feature is specifically adapted for MongoDB databases that havent been preconfigured.
save-job.ts ► INSERT-TEXT-HERE
src.utils
File Summary
parse-priority.ts ParsePriority, situated in the src/utils folder, transforms the priority of jobs from a textual format to a numerical representation. This allows the Pulse system within the repository to handle job scheduling based on priority levels, improving task queue management.
process-jobs.ts ► INSERT-TEXT-HERE
create-job.ts CreateJob function, residing in src/utils/create-job.ts, orchestrates the generation of Job objects within the Pulse application. It complements the parent repositorys architecture by leveraging the Pulse instance and supplied job data to construct and return a Job.
index.ts Facilitates job creation, priority parsing, and job processing, serving as a utility hub within the pulse repository. It critically interlinks these utility functions to streamline task organization and execution, enhancing the repository's overall functionality.
src.job
File Summary
enable.ts Enable.ts activates a specific job type within the pulse project. By modifying an attribute in the Job object, it reverses the disabled status, allowing the job to run. This function integrates seamlessly with the wider repository structure, particularly the job module.
is-running.ts Defines a function that determines if specific jobs within the application are currently running. It uses time comparisons, analyzing lastRunAt and lastFinishedAt properties, to deliver its verdict, thereby enhancing task management in the parent repository pulse.
schedule.ts Schedule.ts in the job directory empowers a certain task to run at a predefined time. Using this feature, users can set either a specific date or a string pattern to determine the next execution instance of a job, thereby enhancing the scheduling capabilities in the overall Pulse project.
touch.ts Touch.ts within the job directory of the Pulse repository manages job concurrency. It updates a jobs lockedAt time, preventing multiple instances from running simultaneously. Can have an optional progress parameter (0-100). The function returns a Promise for the saved job.
compute-next-run-at.ts ► INSERT-TEXT-HERE
to-json.ts Transforms job details into a storable JSON object within the repositorys job management module. Converts key date attributes into the Date data type, facilitating data interchange with MongoDB.
repeat-at.ts RepeatAt is a functionality of the Job module that arranges a task repetition at a specific interval. It accepts human-readable or numeric time variables, thereby empowering developers to schedule tasks dynamically within the pulse project.
set-shouldsaveresult.ts SetShouldSaveResult in the Job directory enables the persistence of a jobs return value by managing the relevant flag. It forms part of the repositorys core functionality, influencing how job results are stored and retrieved within the pulse system.
disable.ts Acting as a crucial component in the pulse repository, src/job/disable.ts provides the functionality to prevent specific jobs from running within the software system by modifying the job attributes. The solution enhances system control and ensures efficient resource allocation.
fail.ts Fail within the job directory of the Pulse repository ensures efficient error handling by marking a job as failed. It records the failure reason, increments the failure count, timestamps it, and debugs the number of times a job has failed, thereby improving transparency and traceability.
priority.ts In the context of the Pulse repository, priority.ts facilitates adjustment of task prioritization within the job queue. It leverages a method to parse and set job priority based on provided parameters, thereby influencing the order of job execution.
remove.ts In the context of the Pulse repository, remove.ts distresses a crucial function within the Job module. It facilitates the removal of a job from MongoDB by cancelling the job identified by its unique _id attribute.
unique.ts Within the broader Pulse repository, the unique.ts file fundamentally manages the uniqueness of a job. It contains a function that allows the creation of unique jobs by adding specific unique attributes and options to the job data.
index.ts ► INSERT-TEXT-HERE
repeat-every.ts RepeatEvery, located within the job directory, enables task scheduling at regular intervals. It includes versatile options such as setting start dates, end dates, skipping specific days, and handling immediate execution scenarios, contributing significantly to the parent repository's task management capabilities.
run.ts ► INSERT-TEXT-HERE
save.ts Save.ts facilitates the persistence of job instances into MongoDB. Working within the job subdirectory of the pulse project, it enables asynchronous saving operations, either successfully storing a job or returning errors.



Getting Started

| Take a look at our Quick Start guide.

Installation

$ npm install --save @pulsecron/pulse

Example

import Pulse from '@pulsecron/pulse';

const mongoConnectionString = 'mongodb://localhost:27017/pulse';

const pulse = new Pulse({
  db: { address: mongoConnectionString },
  defaultConcurrency: 4,
  maxConcurrency: 4,
  processEvery: '10 seconds',
  resumeOnRestart: true,
});

// Or override the default collection name:
// const pulse = new Pulse({db: {address: mongoConnectionString, collection: 'jobCollectionName'}});

// or pass additional connection options:
// const pulse = new Pulse({db: {address: mongoConnectionString, collection: 'jobCollectionName', options: {ssl: true}}});

// or pass in an existing mongodb-native MongoClient instance
// const pulse = new Pulse({mongo: myMongoClient});

/**
 * Example of defining a job
 */
pulse.define('delete old users', async (job) => {
  console.log('Deleting old users...');
  return;
});

/**
 * Example of repeating a job
 */
(async function () {
  // IIFE to give access to async/await
  await pulse.start();

  await pulse.every('3 minutes', 'delete old users');

  // Alternatively, you could also do:
  await pulse.every('*/3 * * * *', 'delete old users');
})();

/**
 * Example of defining a job with options
 */
pulse.define(
  'send email report',
  async (job) => {
    const { to } = job.attrs.data;

    console.log(`Sending email report to ${to}`);
  },
  { lockLifetime: 5 * 1000, priority: 'high', concurrency: 10 }
);

/**
 * Example of scheduling a job
 */
(async function () {
  await pulse.start();
  await pulse.schedule('in 20 minutes', 'send email report', { to: '[email protected]' });
})();

/**
 * Example of repeating a job
 */
(async function () {
  const weeklyReport = pulse.create('send email report', { to: '[email protected]' });
  await pulse.start();
  await weeklyReport.repeatEvery('1 week').save();
})();

/**
 * Check job start and completion/failure
 */
pulse.on('start', (job) => {
  console.log(time(), `Job <${job.attrs.name}> starting`);
});
pulse.on('success', (job) => {
  console.log(time(), `Job <${job.attrs.name}> succeeded`);
});
pulse.on('fail', (error, job) => {
  console.log(time(), `Job <${job.attrs.name}> failed:`, error);
});

function time() {
  return new Date().toTimeString().split(' ')[0];
}



Project Roadmap

  • Add Support for Latest Mongoose Version(8.x.x): Upgrade Pulse to be fully compatible with the latest version of Mongoose. This will enable Pulse to leverage the newest features and improvements in Mongoose, ensuring better performance, stability, and security for applications that rely on MongoDB through Mongoose.
  • Refactoring to Modern TypeScript Syntax: Undertake a comprehensive refactor of the codebase to utilize modern TypeScript features and syntax. This refactoring will improve code readability, maintainability, and make it easier for new contributors to understand and contribute to the project.
  • Resolving Issues in Existing Agenda Projects: Actively address and resolve outstanding issues within the original Agenda project. This initiative not only aids the community by improving the legacy codebase but also informs the development of Pulse by identifying and addressing past challenges.
  • Rewrite Test Code: Revamp our testing suite to increase coverage and ensure tests are up-to-date with modern testing practices. This rewrite aims to enhance test reliability and efficiency, facilitating smoother development and deployment cycles.
  • Rewrite Documentation: Completely revise and update the documentation to reflect all new changes and features, ensure clarity of information, and improve navigation and readability for developers. This effort will include new getting started guides, API documentation, and use case examples to facilitate easier adoption and implementation by users.



Contributing

Contributions are welcome! Here are several ways you can contribute:

Contributing Guidelines
  1. Fork the Repository: Start by forking the project repository to your github account.
  2. Clone Locally: Clone the forked repository to your local machine using a git client.
    git clone https://github.com/pulsecron/pulse
  3. Create a New Branch: Always work on a new branch, giving it a descriptive name.
    git checkout -b new-feature-x
  4. Make Your Changes: Develop and test your changes locally.
  5. Commit Your Changes: Commit with a clear message describing your updates.
    git commit -m 'Implemented new feature x.'
  6. Push to github: Push the changes to your forked repository.
    git push origin new-feature-x
  7. Submit a Pull Request: Create a PR against the original project repository. Clearly describe the changes and their motivations.
  8. Review: Once your PR is reviewed and approved, it will be merged into the main branch. Congratulations on your contribution!
Contributor Graph




License

This project is protected under the MIT License. For more details, refer to the LICENSE file.




Acknowledgments

pulse's People

Contributors

code-xhyun avatar kostysh avatar semantic-release-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

pulse's Issues

Changes to pulseJobs documents collection during Job execution are reverted on document updates

Description

Hi,
will be nice if changes to document into pulseJobs collection are kept even if the updates occurs during execution of job.

For example if you update document filed "disabled" to true while job is running, on first update done by pulse library it will be reverted to its value at the begin of the execution.

I think that Pulse library internally before saving the document into pulseJobs has to read the actual state of job, or update only the fields actually the library needs to update (like lockedAt, progress, lastFinishedAt, ...)

What do you think about this enhancement?

Code example

No response

Additional context

No response

Jobs after creation are not adding to the database

Hi,
please clarify the job workflow.
I am adding jobs using pulse.create('<job_name>', '{job_data}').
When a job is added without errors, it does not appear in the job collection (I have checked via MongoDB console) and _id parameter of a job is undefined.
If a server goes down at this moment all the added jobs will be missed after the server restart.
How do you manage jobs to make it possible to finish all unfinished jobs after the server restart?

By the way, here is my configuration with which I am starting a queue:

const queue = new Pulse({
    name: 'MyQueue',
    db: {
      address: databaseUrl, // a valid connection URL
      collection: 'jobs',
    },
    defaultConcurrency: 3,
    maxConcurrency: 5,
    processEvery: '10 seconds',
  });

Pulse UI

Is there going to a compatible UI one could use together with Pulse just like agendash??

Pulse complete event is called before lockedAt is cleared

Hi, I don't know if this is intentionally done, but the event pulse.on('complete', async (job) => {}) is called before job lockedAt into collection is cleared.

This bring to a consequence: if you call pulse.stop() into complete event stop function (https://github.com/pulsecron/pulse/blob/v1.1.9/src/pulse/stop.ts) will find locked job that is already completed.
This behaviour seems that don't cause any problems, but maybe could be considered that the event complete is emitted after lockedAt is set to null.

Promise pulse.stop() never resolve in some cases

I'm facing a problem calling pulse.stop(), here an examle:

pulse.stop().then(() => {
   console.log('Pulse stopped');
});

The problem is that in case of success of this._collection.updateMany resolve() is not called.
Another problem that may exists is that in case of fail of this._collection.updateMany both reject(error) and resolve() are called.

See https://github.com/pulsecron/pulse/blob/v1.1.9/src/pulse/stop.ts

const _unlockJobs = async (): Promise<void> => {
    return new Promise((resolve, reject) => {
      debug('Pulse._unlockJobs()');
      const jobIds = this._lockedJobs.map((job) => job.attrs._id);

      if (jobIds.length === 0) {
        debug('no jobs to unlock');
        resolve();
      }

      debug('about to unlock jobs with ids: %O', jobIds);
      this._collection.updateMany({ _id: { $in: jobIds } }, { $set: { lockedAt: null } }).catch((error) => {
        if (error) {
          reject(error);
        }

        this._lockedJobs = [];
        resolve();
      });
    });
  };

I'm not sure 100% if the following solution is the best one, but I think it will work

this._collection.updateMany({ _id: { $in: jobIds } }, { $set: { lockedAt: null } })
.then() {
  this._lockedJobs = [];
  resolve();
}
.catch((error) => {
  reject(error);
});

>1.1.2 doesn't compile in TypeScript projects with `dom` library disabled

Description

  1. Have a TypeScript project/codebase without dom type definitions (it can be done through setting tsc --lib es6 or similar).
  2. Install version after (not equal) 1.1.2 (including the latest - 1.5.1).
  3. Import anything from this package.
  4. Compile the project.

Compilation fails with the error:

node_modules/@pulsecron/pulse/dist/job/unique.d.ts:3:42 - error TS2304: Cannot find name 'Document'.

3 export type UniqueMethod<TSchema extends Document = Document> = (filter: Filter<TSchema>, options?: {
                                           ~~~~~~~~

node_modules/@pulsecron/pulse/dist/job/unique.d.ts:3:53 - error TS2304: Cannot find name 'Document'.

3 export type UniqueMethod<TSchema extends Document = Document> = (filter: Filter<TSchema>, options?: {

Code example

Compile this code

index.ts
// import {Document as MongoDocument} from 'mongodb';

// declare module '@pulsecron/pulse/dist/job/unique' {
//   type Document = MongoDocument;
// }

import {Processor} from '@pulsecron/pulse';

const p: Processor<any> = () => {};
package.json
{
  "name": "ts",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "tsc --types node --lib es6 ./index.ts",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@pulsecron/pulse": "^1.5.1"
  },
  "devDependencies": {
    "@types/node": "^20.14.9",
    "mongodb": "^6.8.0",
    "typescript": "^5.5.2"
  }
}

Additional context

Workaround

Add the declaration augmentation file (like src\@types\pulse-fixes.d.ts):

import {Document as MongoDocument} from 'mongodb';

declare module '@pulsecron/pulse/dist/job/unique' {
  type Document = MongoDocument;
}

Or simply uncomment the commented part of the Code example.

Fix

Import Document from mongodb in @pulsecron/pulse/src/job/unique 😀

import { Filter } from 'mongodb';

And disable DOM type definitions by lib in tsconfig.

`Processor` type does not allowing creation of async processors

Here is the actual type:

export type Processor<T extends JobAttributes> = (job: Job<T>, done?: () => void) => void;

So, you cannot define async processors like mentioned in the example:

pulse.define(
  'doJob',
  async (job, done) => { // <-- defining `async` leads to a typescript compiler error: "Promise returned in function argument where a void return was expected."
    try {
      // processor logic
      done(); // <-- also leads to the error "Cannot invoke an object which is possibly 'undefined'"
    } catch (error) {
      console.error('Failed:', error);
    }
  }, {
    concurrency: 5,
    // etc...
});

Also, question: Why the done argument is optional? Where are conditions when done may be defined or not?

TypeError: Pulse is not a constructor

I'm trying to use Pulse (migrated from Agenda). This is my code

import Pulse from '@pulsecron/pulse';

const mongoConnectionString = process.env.MONGO_URL || "mongodb://127.0.0.1:27018/pulse";
const pulse = new Pulse({ db: { address: mongoConnectionString } });

But I got an error that says:

TypeError: Pulse is not a constructor

Can someone explain why it happen and how to fix this? thanks

Enhance Job Query Performance by Adding Indexed Composite Field for Efficient Lookups

I think it's crucial to have a way to query jobs in a more performant way. Here is an example scenario to illustrate the problem:

Example Situation:

A customer books an appointment (Booking entity) for a date 4 weeks in the future. I want to notify the customer 1 week before the appointment starts. To achieve this, I create a job to send the notification at the appropriate time.

If the organizer needs to cancel the appointment due to personal reasons, I would issue a refund and take necessary actions. Additionally, I need to cancel the previously created notification job.

Currently, to achieve this, I would query the metadata field in the jobs collection of MongoDB. However, this field is not indexed, and adding an index to the metadata field could be too expensive in terms of performance and storage costs. This would lead to high costs and inefficiencies when handling a large collection of data, as it would result in MongoDB performing a full collection scan.

Proposed Solution:

In my experience with NoSQL databases, a common approach is to create a single field consisting of attributes that are commonly queried. For instance, we can concatenate the customer ID and booking ID into a single field:

facebook|1234567890;a1a2b8e2-11b1-48d0-adb7-d4647a3e424d

This composite field should be indexed to allow fast querying. Combined with the job name, this would enable very specific and efficient lookups with a single index.

Benefits:

  • Improved performance for querying and managing jobs.
  • Reduced operational costs by avoiding full collection scans.
  • Enhanced scalability for handling a larger volume of jobs.

Implementing this solution would greatly enhance the efficiency and scalability of Pulse.

Note: one could of course make use composite indexes with multiple fields instead of this composite field, but the Pulse API might get too complicated then when one needs to open the whole field and indexing API to the configuration properties of this dependency I think.

Does the `resumeOnRestart` flag work only in one direction?

Hello!
I saw this issue
And I am trying to achieve the exact opposite behavior.
I set resumeOnRestart to false, but if I stop the server and restart it after the scheduled start date, the task still runs...

And within the job data, I also can't find any fields that would help me determine if the task wasn't completed on time and discard it. For one-time tasks, you can use the start time, but for cron tasks, it's problematic.

This behavior is unexpected.

Desired behavior:
The task should run every half hour (at xx:00 and xx:30 each hour). If the server was turned off at xx:20 and turned back on at xx:40, the server should not run the missed task at xx:40.

error with first installation - Error: Cannot find module '@src/utils'

Description

I tried the sample code from the npm - https://www.npmjs.com/package/@pulsecron/pulse
I also tried to use es6 syntax and regular node.js syntax , I still get this error.

Code example

node:internal/modules/cjs/loader:1056
throw err;
^

Error: Cannot find module '@src/utils'
Require stack:

  • /home/matan/pulse-agenda/node_modules/@pulsecron/pulse/dist/pulse/every.js
  • /home/matan/pulse-agenda/node_modules/@pulsecron/pulse/dist/pulse/index.js
  • /home/matan/pulse-agenda/node_modules/@pulsecron/pulse/dist/index.js
  • /home/matan/pulse-agenda/index.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1053:15)
    at Module._load (node:internal/modules/cjs/loader:898:27)
    at Module.require (node:internal/modules/cjs/loader:1120:19)
    at require (node:internal/modules/helpers:112:18)
    at Object. (/home/matan/pulse-agenda/node_modules/@pulsecron/pulse/dist/pulse/every.js:5:17)
    at Module._compile (node:internal/modules/cjs/loader:1239:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1293:10)
    at Module.load (node:internal/modules/cjs/loader:1096:32)
    at Module._load (node:internal/modules/cjs/loader:935:12)
    at Module.require (node:internal/modules/cjs/loader:1120:19) {
    code: 'MODULE_NOT_FOUND',
    requireStack: [
    '/home/matan/pulse-agenda/node_modules/@pulsecron/pulse/dist/pulse/every.js',
    '/home/matan/pulse-agenda/node_modules/@pulsecron/pulse/dist/pulse/index.js',
    '/home/matan/pulse-agenda/node_modules/@pulsecron/pulse/dist/index.js',
    '/home/matan/pulse-agenda/index.js'
    ]
    }

Additional context

No response

Migration from agenda

We have a project that has been running for several years on Agenda (currently at v5). We're planning an upgrade from MongoDB 5 to MongoDB 7 and are considering moving to Pulse due to Agenda no longer being maintained.

Given Pulse was started as a fork of Agenda, is it backwards compatible - i.e. can I swap out the libraries, ensure Pulse connects to the same collection, and expect existing scheduled tasks to continue running in the same way?

`JobAttributes` not typed correctly

I just tried Pulse and faced an issue with a job processor definition type.
Here is a short example:

import { JobAttributes, JobAttributesData } from '@pulsecron/pulse';

interface ProcessJobData extends JobAttributesData {
  myId: string;
}

pulse.define<JobAttributes<ProcessJobData>>(
    'processJob',
    async (job) => {
      const { myId } = job.attrs.data; // `data` here is `any` of type, but must be `ProcessJobData` of type
      // ...
    },
    {
      concurrency: 3,
      priority: 'normal',
    },
  );

The issue is, possibly, here:

export interface JobAttributes<T extends JobAttributesData = JobAttributesData> {
    _id: mongodb.ObjectId;
    pulse: Pulse;
    type: string;
    name: string;
    disabled?: boolean;
    nextRunAt?: Date | null;
    lockedAt?: Date | null;
    priority: number | string;
    data: any; // <-- should be T, not any
    uniqueQuery?: any;
    uniqueOpts?: {
        insertOnly: boolean;
    };
    repeatInterval?: string;
    repeatTimezone?: string | null;
    repeatAt?: string;
    lastRunAt?: Date;
    lastFinishedAt?: Date;
    startDate?: Date | number | null;
    endDate?: Date | number | null;
    skipDays?: string | null;
    failReason?: string;
    failCount?: number;
    failedAt?: Date;
    lastModifiedBy?: string;
    shouldSaveResult?: boolean;
    result?: unknown;
}

Return type of the `CreateMethod` is not correct

Here is the type of the CreateMethod:

export type CreateMethod = <T extends JobAttributesData>(name: string, data: T) => Job; // `Job` is not properly typed

Job itself has the following type:

declare class Job<T extends JobAttributesData = JobAttributesData> { /* ... */ }

This way a return type of the CreateMethod has to look like this:

export type CreateMethod = <T extends JobAttributesData>(name: string, data: T) => Job<T>;

Error: Cannot find module '@src/utils'

Description

Something wrong has been introduced with the latest minor version.
Unable to start an application with @pulsecron/pulse v1.4.2 (there are no issue in the 1.4.1)

Here is an example of the error:

Error: Cannot find module '@src/utils'
Require stack:
- /<path>/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]_viudxiygyx73fygsmtzmuc5qs4/node_modules/@pulsecron/pulse/dist/pulse/every.js
- /<path>/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]_viudxiygyx73fygsmtzmuc5qs4/node_modules/@pulsecron/pulse/dist/pulse/index.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1143:15)
    at Module._load (node:internal/modules/cjs/loader:984:27)
    at Module.require (node:internal/modules/cjs/loader:1231:19)
    at require (node:internal/modules/helpers:179:18)
    at Object.<anonymous> (/<path>/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]_viudxiygyx73fygsmtzmuc5qs4/node_modules/@pulsecron/pulse/dist/pulse/every.js:5:17)
    at Module._compile (node:internal/modules/cjs/loader:1369:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
    at Module.load (node:internal/modules/cjs/loader:1206:32)
    at Module._load (node:internal/modules/cjs/loader:1022:12)
    at Module.require (node:internal/modules/cjs/loader:1231:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/<path>/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]_viudxiygyx73fygsmtzmuc5qs4/node_modules/@pulsecron/pulse/dist/pulse/every.js',
    '/<path>/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]_viudxiygyx73fygsmtzmuc5qs4/node_modules/@pulsecron/pulse/dist/pulse/index.js'
  ]
}

Code example

No response

Additional context

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.