In my quest to build one of the easiest and most versatile libraries for building Hive blockchain applications, I have added quite a few features to Hive Stream. The largest feature to date is code contracts allowing you to build applications that react to blockchain payloads, furthermore, also adding in the ability to create adapters to use different types of databases such as SQLite and MongoDB.
Well, today I want to talk about one of the newest and I think most powerful additions to Hive Stream: time-based actions.
A time-based action allows you to specify that an action will take place after an allotted amount of time has passed. Traditionally, this would be achieved using cron jobs (a task that is told to run at a specific date/time or number of times).
Theoretically, if you're familiar with cron jobs, you can already use them to perform time-based actions, but for others not wanting to delve into server-level operations, they can be intimidating. What if you wanted to write a contract that gets executed every hour? A good use case for this is a lottery. You want to run an hourly lottery or perhaps a lottery to draw every 24 hours.
The workflow might resemble something like this:
At their core, a time-based task is nothing more than a few parameters stored in a database/file. On load of the library, all actions are loaded into memory with their appropriate timestamps. If a time-based action is added during execution, it automatically gets loaded into memory and saved into our storage.
An action just needs a time value, a unique ID and the name of a contract as well as method inside of the contract to be executed.
import { TimeAction } from 'hive-stream';
const runDraw = new TimeAction('1h', 'rundraw', 'lotto', 'rundraw');
const ss = new Streamer();
ss.registerContract('lotto', lottoContract');
ss.registerAction(runDraw);
On the surface, the API is quite simple. Behind the scenes, a little bit of magic is used to ensure that actions run when they're supposed to. Every three seconds, the Hive Blockchain produces a new block. We can leverage this to run actions as low as three seconds.
The base time is constantly updated every 3 seconds from the Hive blockchain and this is used to form the basis of the date/time checks. When an action is created, the creation date is stored along with it. The blockchain is a great timer in that blocks are consistently being produced.
Actions are stored in memory, and whenever a block is processed we check to see if any of the actions should be run. For this reason, it is advisable you don't go adding in hundreds of actions to your application.
The README in the GitHub repository explains time-based actions in more detail.
Software is never perfect, eventually, your server will crash or the streamer needs to be reset. If everything was kept in memory, we'd lose it every time. For this reason, you need to use an adapter that can persist in action data.
When an action is registered, it gets stored in either your database or a local file. Actions are compatible with the three adapters that ship with Hive Stream; File (a local JSON file), SQLlite (a local database) and MongoDB. On start, the streamer will check if there are any registered actions and the state will be preserved.
When actions are registered, we store a date. So, if you restart and your hourly action was 5 minutes off being run, it'll still run in 5 minutes. Similarly, if your server goes down and a task that was meant to run was missed, it will be run again. As a safeguard, if multiple actions calling the same contract and method are fired, only one of those will be called.
Please keep in mind if your server goes down or you stop your node and the amount of time in between exceeds that of your action, it will still run, but it won't be a precise measure of time if your server goes down for two hours and you had a 30-minute task, for example.
At present, there are no unit tests for any of this, so it is not advisable to rely on time-based actions just yet. Having said that, I encourage you to try them out now. In the next couple of days tests and improvements will be made to make them safer and more reliable. There will be bugs and missed things, but be patient.