Search code examples
node.jsherokudiscord.js

Excute script before cycling (Heroku node.js discord bot)


I'm making a discord bot and I'm trying to save data in a private server where my bot can always get access to. Now I have done the save & load function, the only problem is, when do I save? I can send the data in the channel every minute, but that will spam the channel too much. I wonder if there's a more effeicient way to do this.

That is, is it possible to detect the heroku platform is going to start cycling, so I can make the bot save the data before it starts the cycling process- is there a way heroku provides to do that? (or maybe alternatively, track the time when heroku is going to cycle)

Part of bot.js:

// backup when start

client.on('ready',()=>{
    console.log(`${client.user.tag} ready!`);

    client.channels.fetch(dataChannelId)
        .then(channel => {
            dataChannel = channel;
        
            console.log(dataChannel.id);
    
            dataBackup(true);
        });
});

// save - when?

dataSave(mainChannel, currentQuestionAns, currentQuestionReward, currentQuestionMessage, miliheads);

Solution

  • There does not seem to be a way to detect exactly when cycling will happen, but:

    From Heroku:

    The cycling happens once every 24 hours (plus up to 216 random minutes, to prevent every dyno for an application from restarting at the same time).

    In addition, dynos are restarted as needed for the overall health of the system and your app. For example, the dyno manager occasionally detects a fault in the underlying hardware and needs to move your dyno to a new physical location.

    Therefore, theoretically, a Dyno should have around 24 hours before cycling, meaning you could schedule your cleanup scripts to be run after about 24 hours:

    setTimeout(() => {
      dataSave(mainChannel, currentQuestionAns, currentQuestionReward, currentQuestionMessage, miliheads);
    }, 24 * 55 * 60 * 1000); // 24 hours - 5 minutes
    

    However, if the dyno restarts before this 24 hour period (due to hardware issues, or an error in your code), you may lose data. If you want to avoid this, you can save more often, such as every minute, or every time the values change, and accept the spam.

    You can also programmatically force the dyno to restart using the Heroku v3 API. This can be used after you backup your data to ensure your bot restarts using the latest data. Restarting this way also resets the 24 hour counter:

    // example uses got, but any HTTP request package should also work
    got.delete({
      url: `https://api.heroku.com/apps/${appName}/dynos`,
      headers: {
        "Content-Type": "application/json",
        "Accept": "application/vnd.heroku+json; version=3",
        "Authorization": `Bearer ${token}`
      }
    });
    

    Since it seems like you are using discord messages to back up your data, but the amount of times you save it doesn't seem to matter, you can also try editing the message(s), rather than sending new messages each time you make a backup.

    function dataSave(/* ... */) {
      const backupMessage = await mainChannel.messages.fetch("id of a message sent by your bot");
      backupMessage.edit(/* ... */);
    }
    

    Another idea for saving your data would be to use a cloud database, such as firebase or something similar.