Epoch Interruption
When executing WASM code it is sometimes useful to set a limit on how long it can run for. This can be used to prevent potentially malicious or buggy code from running forever and slowing down your application. Wasmbox includes two mechanisms to do this, Epoch Interruption and Fuel Usage.
Epoch interruption allows a deadline to be set, once that deadline has passed executing code will immediately terminate execution. Epochs are not automatically incremented, your own script must be increasing the epoch when you wish to indicate that time has passed. For example WASM executing within a Job while the main thread increments the epoch every frame.
Epoch Interruption is faster than fuel usage, but requires another thread to increment epochs.
Enabling Epoch Interruption
Epoch Interruption must be enabled in the EngineConfig
used to load a WASM Asset:
EngineConfig config = EngineConfig.Default;
config.UseEpochInterruption = true;
If the WASM Asset is precompiled it must also be enabled in the importer:
Setting A Limit
The Epoch limit is set on a Store
, all Instances
sharing a Store
share the same epoch deadline.
Store store; // Get a store from somewhere
store.SetEpochDeadline(100);
Incrementing The Epoch
The epoch is incremented on the Engine
, through an EngineConfig
.
All WASM Instances loaded with the same EngineConfig
share the same epoch. Use EpochGroup
to split up identical engine configs if necessary.
EngineConfig config = EngineConfig.Default;
var handle = config.GetEpochGroup();
if (handle == null)
throw new NotImplementedException("handle is null if config.UseEpochInterruption is false!");
handle.SetEpoch(Time.frameCount);
Handling An Epoch Timeout
WASM function calls through the Wasmbox generated wrapper code have two trap handling methods: exceptions and results. Set the Trap Handling
option in the importer to choose which one to use.
- Exception
- Result
try
{
var value = wrapper.hello();
Debug.Log("WASM Result: " + value);
}
catch (TrapException ex)
{
Debug.LogError("WASM Trap: " + ex.Type);
}
var result = wrapper.hello();
if (result.Type == ResultType.Ok)
{
var value = result.Value;
Debug.Log("WASM Result: " + value);
}
else
{
Debug.Log("WASM Trap: " + result.TrapCode);
}