2

I have a model and I want to set a timer such that after an instance of the model is created, a timer is counting down for 1 hour. When timer expires, I want to be able to execute a script. Any ideas?

var mongoose = require ('mongoose');
var Schema = mongoose.Schema;

var mySchema = new Schema({
    timer: {
        type: Date,
        expires: '1h'
    }
});

Edit:

Andy here. I'm the creator of the bounty and am not the original poster. I opened this bounty because I haven't figured out a way to confidently track an expiring document. I'm using mongoose-cron to create a job for each user created match. If there are no issues with the server (restarts/crashes/etc.) the cron job expires on time (24 hours) and I set an expired property to false for the associated document.

The problem is when the server has some sort of interruption. In that case, the cron job is destroyed or—at least—disassociated with the closure I created (feeding in the correct document). Because of this, I don't think cron jobs are the answer and am hoping to find an approach I can trust in production environments.

Andy Hoffman
  • 18,436
  • 4
  • 42
  • 61
SalmaFG
  • 2,022
  • 3
  • 23
  • 36

2 Answers2

0

It seems more a logic work than a Mongoose Schema job. Why do not execute a script on the server when an instance is created?

Maybe, no guaranty, you can do it your way with mongoose-cron npm module. You could also have a look at mongoose-function who seems interesting too.

Another possibility you can try to store function (a bit like SQL stored procedure), but again this is apparently not encouraged as it is said in this answer.

Community
  • 1
  • 1
TGrif
  • 5,725
  • 9
  • 31
  • 52
0

Please consider this following solution.

A separate notifications project to handle all the timer related functionality.

  1. As soon as instance of Model is created register a cron event with data and store it in database.
  2. notifications module check for upcoming cron event in database and execute as soon as timer expire with data.

As maintaining timer is independent from model creation so restart server can be maintain easily.

I have a notifications github project that can register cron event and store it in database and execute it after completion.

In notifications i am sending email after cron completion you can handle as per your requirement.

Change sendNotification method in file notifications/app/message.js

messages.sendNotification = (data) => {
    if(data.length === 0){
        logger.info(`No notifications to send on ${moment().format("YYYY-MM-DD")}`);
        return;
    }
    data.forEach(function (row) {
        mailer.send({
            subject:"Notifications Message",
            to:row.recipient_email,
            text:row.data
        },updateNotificationStatus(row));
    });
};

Configure notifications to fetch latest cron events from database as per your need.

Source file - /notifications/config/config.js

config.CRON_JOB_RULE = "0 11 * * *"; // daily at 11 am

For cron register you have to make POST request /notifications with json data.

Sample POST request

var data = {
          "email":"",
          "date":"",
          "message":""
      };

$.ajax({
            url:"/notifications",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType:"json",
            data:JSON.stringify(data)
        });
front_end_dev
  • 1,998
  • 1
  • 9
  • 14
  • Interesting approach for scalability , but you said this "As maintaining timer is independent from model creation so restart server can be maintain easily". For this to be true the DB code for moving the document must be in timer project yes? – LumbusterTick Jul 23 '20 at 07:29
  • @LumbusterTick not necessarily you can save only the document id and when notification is trigger you got the data ( any json structure ) and do your computation – front_end_dev Jul 24 '20 at 08:41