Add a failover manager for script redundancy.
This commit is contained in:
62
Mixins/FailoverManager/readme.md
Normal file
62
Mixins/FailoverManager/readme.md
Normal file
@ -0,0 +1,62 @@
|
||||
# Failover Manager for SE scripts
|
||||
|
||||
This mixin allows multiple Programmable Blocks to coordinate with each other so only one copy of the script is running at a time; all but one block act as backup nodes that will be automatically activated (in priority order) in the event the active node goes offline.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* Everything assumes you're using [MDK2](TODO). Using this without MDK is possible, but is outside the scope of this documentation. (You probably just need to copy everything inside the `partial class Program` block for each mixin you're using into your own script, but I can't guarantee support for problems you encounter)
|
||||
* This requires my Console mixin as well. If you don't want to use that mixin's full functionality, you can use an EchoConsole (example below).
|
||||
* If you aren't using MyIni to configure your script's blocks, you can also just pass `new MyIni()` and avoid instantiating an entire property
|
||||
|
||||
## Usage
|
||||
|
||||
This code is designed to be as drop-in as possible once you meet the prerequisites above. Usage should look something like this:
|
||||
|
||||
```
|
||||
public partial class Program : MyGridProgram
|
||||
public MyIni Ini { get; } = new MyIni();
|
||||
public IConsole Console { get; private set; }
|
||||
|
||||
private FailoverManager _failover;
|
||||
|
||||
public Program() {
|
||||
Console = new MainConsole(this, "Script Name");
|
||||
_failover = new FailoverManager(this, Console, Ini);
|
||||
|
||||
// alternate instantiation with Stub Console and fresh MyIni instance.
|
||||
// If you do it this way, you don't need the `Ini` or `Console` properties above.
|
||||
// _failover = new FailoverManager(this, new EchoConsole(this), new MyIni());
|
||||
|
||||
// The script *must* start out with periodic updates, even if it is
|
||||
// a script that's only triggered conditionally (though in that case),
|
||||
// see caveats.
|
||||
Runtime.UpdateFrequency = UpdateFrequency.Update100;
|
||||
|
||||
// ... script initialization happens here
|
||||
}
|
||||
|
||||
public void Main(string argument, UpdateType updateSource) {
|
||||
// This basically instructs the script to "go back to sleep"
|
||||
// if it isn't the active node.
|
||||
if (_failover.ActiveCheck == FailoverState.Standby) return;
|
||||
|
||||
// If you need more complicated "warm-up" logic when your script
|
||||
// becomes active, (for example, changing the update frequency) you can use this.
|
||||
// This statement will only be true once, when the script first takes over control.
|
||||
//
|
||||
// This is optional and depends on your use case.
|
||||
if (_failover.ActiveCheck.HasFlag(FailoverState.Failover)) {
|
||||
// Code that should run once when this script becomes the active node goes here
|
||||
}
|
||||
|
||||
// ... your script logic goes here
|
||||
}
|
||||
```
|
||||
|
||||
Scripts that are using failover also need configuration in their Programmable Blocks' Custom Data. That should look something like this:
|
||||
|
||||
```
|
||||
[failover]
|
||||
id=scriptName # This must match for all running copies of the script.
|
||||
rank=0 # The lowest ranked copy of the script will be the primary node, and they will failover in ascending rank order
|
||||
```
|
Reference in New Issue
Block a user