onScheduledEvent improvement

OnScheduledEvent is run whenever a schedule is created, deleted, updated or run. This makes it so that you have to create conditions that check that the scheduled event was triggered because of the scheduled time or a CRUD method. I believe the payload should include this information to make it easier for devs to distinguish between each event type.

3 Likes

Hi @osanchez,

The event, OnScheduledEvent will only run the scheduled time comes up again. This will not run whenever the schedule is created, updated, or deleted.

So, the payload does not need any differences as it is always run when the set scheduled time comes again.

Do you mean any other behavior or a feedback on its current behavior?

We have the following registered event with callback function that runs a sync when this event is triggered. There is another server function that is called when our custom iparams page is saved. this server function creates, updates, or deletes the schedule. When we were saving the configuration page settings the onScheduledEvent was being triggered. As you mention, it should only be triggered when the scheduled time is reached, but for us this does not seem to be the case. please let me know if you would like to see more source code.

events: [
      { event: "onScheduledEvent", callback: "onScheduledEventHandler"}
  ]

@osanchez I understand the issue that you report.

When the iparams are updated, the onAppInstall event will get triggered. Could you share the source code of that function to understand what has been done on the callback function?
Please remove any business logic written there and just share the code snippet on how the schedule event is created/updated/deleted.

Here are the events

  events: [
      { event: "onScheduledEvent", callback: "onScheduledEventHandler"},
      { event: "onAppInstall", callback: "onAppInstalledCallback"}
  ]

OnAppInstall

    onAppInstalledCallback: function(payload) {
        console.log("Logging arguments from onAppInstallevent: " + JSON.stringify(payload));

        $db.set('D42-Settings', {.....}).then(
            function() {
                console.log('Production environment flag set')
            },
            function(error) {
                console.log('Failed to set production environment flag')
                console.log(error)
            }
        )
        renderData();
  },

Here is the scheduled event

onScheduledEventHandler: function(payload) {
    console.log("Logging arguments from onScheduledEvent: " +  JSON.stringify(payload));

    if("name" in payload.data) {
        if(payload.data.name === "sync") {
            console.log('Device42 scheduled sync event')
            //check if the current event was triggered due to a scheduled event
            let scheduled_time = payload.iparams.scheduleTime
            let event_trigger_time = new Date(payload.timestamp)

            //time conversion
            let hours = militaryTimeHour(event_trigger_time.getUTCHours());
            let minutes = event_trigger_time.getMinutes();
            event_trigger_time = hours + ':' + minutes

            console.log("scheduled sync time: " + scheduled_time)
            console.log("current event time: " + event_trigger_time)

            //if a sync was not kicked off then the event was likely a CRUD operation on the sync schedule
            if(scheduled_time === event_trigger_time) {
                console.log('starting the scheduled sync')
                let obj = this;
                try {
                    //sync occurs here
                } catch (e) {
                    console.log(e);
                }
            }
        }
    }
    renderData();
  },

triggered on iparams save
Schedule Change

  scheduleChanged: function(args) {
    var scheduleEnable = args.scheduleEnable;
    var scheduleTime = args.scheduleTime;

    $schedule.fetch({
      name: "sync"
    })
    .then(function() {
      if(scheduleEnable)
      {
        $schedule.update({
          name: "sync",
          data: {name: "sync"},
          schedule_at: formatScheduleTime(scheduleTime),
          repeat: {
            time_unit: "days",
            frequency: 1
          }
        })
        .then(function() {
            renderData(null,  {"message": "update schedule successfully."});
        }, function(err) {
            renderData(null,  err);
        });
      } else {
        $schedule.delete({
          name: "sync"
        })
        .then(function() {
            renderData(null,  {"message": "removed schedule"});
        }, function(err) {
            renderData(null,  err);
        });  
      }
    }, function() {
        if (scheduleEnable) {
            $schedule.create({
                name: "sync",
                data: {name: "sync"},
                schedule_at: formatScheduleTime(scheduleTime),
                repeat: {
                    time_unit: "days",
                    frequency: 1
                }
            })
                .then(function () {
                    renderData(null, {"message": "update schedule successfully"});
                }, function (err) {
                    renderData(null, err);
                });
        } else {
            return renderData(null, {"message": "schedule was not updated"});
        }
    })
  },

@osanchez,

Thank you for providing the requested.

  1. So, as soon as iparams are installed, In server.js, scheduleChanged serverless method is invoked – Which has the functionality to fetch, update, delete and create schedules. Which I think you meant by this part,
  1. On this scheduled time and date via scheduleChanged, onScheduledEvent’s business logic is invoked with onScheduledEventHandler serverless method.

When you say,

I assume the payload that you are referring to is the payload that you get inside onScheduledEventHandler serverless method. I am trying to understand structure CRUD information that you think developers need.

// Do you think something like this will help?
{
schedule: {
name: 'sync',
status: 'create'
last_invoked:'<Date_Time>'
}
}

Do you suggest something like this would help?

Hi @Saif, what you have suggested should work. The status for the event can be one of the following [Create, Update, Delete, Trigger]. Where Trigger means that a scheduled event was triggered due to the scheduled time being reached. I believe this will allow users to work with this event in many different ways.

{
schedule: {
name: 'sync',
status: 'create'
last_invoked:'<Date_Time>'
}
}

@osanchez I have tested your use-case and found that the scheduled event works as expected and it does not get triggered whenever CRUD operations happen over the schedule.

According to your case, the scheduleChanged method gets called on iparams save with your custom logic and the CRUD operations happen on the scheduled event based on the use-case.

In this case, whenever the scheduler is created/updated/deleted, the onScheduledEventHandler method should not get triggered. I was able to test and confirm that this does not happen.
If it happens, it’s an issue. Please confirm.

For your feedback on adding the meta information of the scheduled event in the payload, it may not be required if the scheduled events work as expected, I believe.
Do you mean any other information to be added to the payload anyway?

the schedule is being saved using a custom iparams page. On the postConfigs functions there is a server method invoked. It is posted below. This is occurring in a production environment after installing the application as a custom application. My apologies if I have already included this information.

//apply schedule
                client.request.invoke('scheduleChanged', options)
                    .then(
                        function(data) {
                            console.log("Request ID: " + data.requestID);
                            console.log("message: " + data.response.message);
                        },
                        function(err) {
                            console.log("Request ID: " + err.requestID);
                            console.log("error status: " + err.status);
                            console.log("message: " + err.message);
                        }
                    ).catch(function(error) {
                    console.log(error)
                });

The server function is in a prior post and is named ScheduleChanged

This topic was automatically closed after 5 days. New replies are no longer allowed.