-
Notifications
You must be signed in to change notification settings - Fork 55
Creating Programs
Quorum uses the "Operating System Model" for its running code. This gives it the ability to adapt as load is put on the system while also letting systems run more overall by running less important or really expensive code less often.
The functional code in Quorum is divided up into programs. Each program manages a specific aspect of the system and is capable of launching its own children programs.
Here we start with a simple program that prints Hello World
to the console.
class HelloWorld extends kernel.process {
main () {
Logger.log('Hello World!')
}
}
module.exports = HelloWorld
This program is as simple as it gets- the main
function, which is called every time the program is run, uses the Logger
library to print 'Hello World'. The program extends from the kernel.process
class which makes sure this program has everything needed for the kernel to run it.
Each process (which is an instance of a running program) has its own datastore that is unique and isolated from other processes. This datastore persists between ticks but gets cleared automatically when the process dies. Accessing this datastore is done through this.data
.
class Counter extends kernel.process {
main () {
if (!this.data.count) {
this.data.count = 1
} else {
this.data.count++
}
Logger.log(`I've been called ${this.data.count} times!`)
}
}
module.exports = Counter
Once a program is finished it should be properly closed, which can be done using this.suicide
.
class Countdown extends kernel.process {
main () {
if (typeof this.data.countdown === 'undefined') {
this.data.countdown = 1
} else {
this.data.countdown--
}
if (this.data.countdown === 0) {
return this.suicide()
}
Logger.log(`Shutdown in ${this.data.countdown} ticks!`)
}
}
module.exports = Countdown
There are two main ways to launch new programs from inside other programs- launchProcess
and launchChildProcess
- although in almost all cases you will want launchChildProcess
. Children processes are attached to their parents and will stop running if their parent process does, while programs created with launchProcess
will run until they close themselves.
When launching processes a label, program name, and (optionally) data are passed to the launching function. Labels are used to keep track of which programs are already running and to prevent multiple copies of the same program from running every tick- if a launch process is called and the label already has a PID attached to it then a new process will not be launched until that first one finished. The name
field is the name of the file itself, in all lowercase and with the folder delimiter converted to underscores (city/mine.js
to city_mine
).
The final field, data
, gets passed to the new process and is used to populate its initial data
object.
Putting this all together we can launch the above CountDown
program and set it to run for 30 ticks instead of the default ten.
class Player extends kernel.process {
main () {
this.launchChildProcess('30 second countdown', 'countdown', {'countdown': 30})
}
}