Behavior workers
Virtufin.Behavior.DevKit turns any Virtufin.Core behavior (IProcess,
IAsyncProcess, IDecide, IIndicator, IExecutor, IAlgebra) into a
worker by binding it to CloudEvents:
public sealed class MyWorker() : BehaviorWorkerBase(
"my", // worker type: names the source and errors
myProcess.FromCloudEvents(Decode) // decode, or Decoded<T>.Skip
.ToCloudEvents(Encode) // zero or more Outgoing per step
.RequireConfig("scenarioid")); // checked before stepping
BehaviorWorkerBase is an IMultiOutputWorker: one input may produce zero,
one or several outputs, each with its own id, type, topic and subject, and the
common envelope (carried extensions, inherited eventtime). The domain devkits
are thin layers over it: StrategyWorkerBase (strategy-devkit),
ExecutorWorkerBase (execution-devkit), IndicatorWorkerBase
(indicator-devkit) and MarketDataWorkerBase (market-data-devkit).
Composing processes
BehaviorExtensions holds the generic combinators; every result is a plain
value, testable without WorkManager or CloudEvents:
| Combinator | Result |
|---|---|
process.AsAsync() |
lifts an IProcess to IAsyncProcess |
algebra.AsProcess() |
an IAlgebra as a process whose output is the folded state |
process.PerKey<…, TKey>() |
one independent copy of the process per key (e.g. per symbol) |
The domain adapters live with their domains: decide.WithPortfolio(algebra)
in Strategy.DevKit, executor.AsAsyncProcess() in Execution.DevKit, and
indicator.AsProcess() in Indicator.DevKit.
Binary payloads
A binding's decoder normally receives the event's JSON payload, decoded by the
strict codec (StrictJsonCodec), where a payload that is not JSON is an error.
For a payload that is not JSON (an order book image, a FlatBuffers sample),
construct the worker with LenientJsonCodec
(BehaviorWorkerBase(workerType, new LenientJsonCodec())): such an event
decodes to an empty object and the decoder reads CloudEvent.Data (bytes) from
the event it is given.
Names
NameFragments.For(typeof(MyWorker)) composes the worker's naming registry:
virtufin.core, every fragment embedded in the worker's assembly, and the
fragments this package owns, virtufin.worlds and virtufin.trading (see
Naming). Names are never built by hand.
Testing
BehaviorTestHost drives a worker in-process: ProcessAllAsync returns every
output of one input, and Payload decodes an output's JSON data.
Moved here from strategy-devkit in 0.31.0, with the naming fragments it owns.