FastMM documentation
FastMM C++ API 0.6.0
Public headers, tier 1 and tier 2
Loading...
Searching...
No Matches
session.hpp
Go to the documentation of this file.
1#pragma once
2// run_live(): wires venues, rings, the engine and the journal into the plan 5.1 thread model and
3// runs a session (fastmm::live, src/live/session.cpp). fastmm::cli::live (cli/live.hpp) is the
4// command line around it.
5//
6// fm-net-<i> one per venue: net::Reactor loop (connections, parsing into the venue's md and
7// order rings, draining the venue's outbound ring when the engine wakes it)
8// fm-engine Engine<S, TscClock, LiveTransport, RingFeed>::run() (pinned / spin mode from
9// [engine] cpu / spin_mode)
10// fm-journal JournalFileWriter drain thread (when journaling)
11// log sink Logger::start(): formats and writes log records from every thread's ring
12// main thread control: posts Venue::on_timer every second, prints stats, recalibrates the
13// TSC every [engine] tsc_recalibrate_s and publishes it (the engine and the
14// venues pick it up), handles SIGINT/SIGTERM and --duration: kill switch ->
15// cancel_all on every venue over an independent REST connection -> stop, all
16// within ~5 s. It also watches the engine's kill switch: a kill the engine trips
17// itself (risk limit, full ring, every venue killed) runs the same shutdown and
18// exits with kExitKilled when [engine] on_kill = "exit" (the default); with "stay"
19// the session keeps running and logs an ERROR line every 10 s. Venue kills are
20// logged once per venue.
21//
22// [engine] threading = "single" (one venue): no fm-net-0; fm-engine runs the venue's reactor
23// iteration between engine steps (Engine::run_inline), takes each market-data event as the venue
24// commits it (EventSink drain hook -> Engine::drain) and hands its orders to Venue::send_now.
25//
26// The thread set is fixed for the whole session (the logger keeps a ring per thread). The strategy
27// is built by the StrategyRegistry's TransportKind::Live factory for [strategy] name; register it
28// (register_builtin_strategies, a strategy module) before calling run_live, or pass a
29// LiveStrategy (fastmm_live._live runs Python hot strategies that way). run_live installs
30// process-wide SIGINT/SIGTERM handlers and restores the previous ones when it returns.
33
34#include <cstdint>
35#include <functional>
36#include <memory>
37#include <string>
38#include <utility>
39#include <vector>
40
41namespace fastmm {
42class IEngineRunner;
43class MsgRing;
44class ParamSchema;
45struct RunnerDeps;
46} // namespace fastmm
47
48namespace fastmm::live {
49
50// A strategy the caller builds instead of the registry's [strategy] name.
51struct LiveStrategy {
52 std::string name; // journal header, status file and log lines
53 const ParamSchema* params = nullptr; // the journal's parameter table
54 std::string meta; // the journal's strategy metadata (`key=value` lines)
55 // Rings the engine polls besides the venues' (parameter updates); the caller keeps them alive.
56 std::vector<MsgRing*> inputs;
57 // Called with a function that wakes the engine, before the session's threads start, and with an
58 // empty one before the session returns. With spin_mode = "adaptive" an idle engine blocks; a
59 // producer on `inputs` calls the function after each push, or its message waits up to 1 ms.
60 std::function<void(std::function<void()> wake)> set_waker;
61 // Builds the runner on `deps` (deps.backend is a LiveBackend) on the calling thread, after the
62 // venues' reference data has loaded and before any session thread starts. An exception or
63 // nullptr gives kExitConfig.
64 std::function<std::unique_ptr<IEngineRunner>(RunnerDeps& deps)> make;
65 // Called after the engine thread has stopped, before the runner is destroyed.
66 std::function<void(IEngineRunner& runner)> finished;
67 // The control socket's `param`: validates the (name, value) pairs against this strategy's schema
68 // and publishes them onto one of `inputs` (the caller owns the publisher, so its copy of the
69 // parameters stays the only one). Returns the error message, empty on success. Unset: the
70 // session answers `param` with an error.
71 std::function<std::string(const std::vector<std::pair<std::string, std::string>>&, InstrumentId)>
73};
75struct LiveOptions {
76 std::string config_path;
77 std::int64_t duration_ns = 0; // 0 = until SIGINT/SIGTERM
78 bool dry_run = false;
79 std::string record_raw_dir;
80 std::string journal_path; // overrides [engine] journal_dir
81 bool no_journal = false;
82 std::string status_path; // overrides the default /dev/shm/fastmm-<engine>.status
83 bool no_status = false;
84 // Control socket (live/control_socket.hpp); empty takes <journal_dir>/<engine name>.ctl.
85 std::string control_path;
86 bool no_control = false;
87 // Removes the durable kill state before starting: clears a latched max-loss trip and arms the
88 // whole [risk] max_loss budget again ([engine] kill_file).
89 bool clear_kill = false;
90 // Waits for the instance lock (live/instance_lock.hpp) instead of refusing to start while another
91 // process holds it; [engine] instance_lock is implied. Warm when every trading venue can hold its
92 // private channels back (Venue::defer_private) and replays its executions before quoting, the
93 // session is split-threaded and not attached to a gateway: market data, books and the strategy
94 // run, orders are refused until the first reconciliation, and the kill file, the strategy state,
95 // the store, the status file, the control socket and the private channels wait for the lock.
96 // Otherwise cold: the reference data and account fees are loaded (attached: nothing), and
97 // everything else waits for the lock.
98 bool standby = false;
99 // standby, and once ready send `handoff` to the control socket of the session holding the lock;
100 // give up after [engine] handoff_timeout_ms without the lock (kExitLocked).
101 bool takeover = false;
102 std::string program = "fastmm-live"; // prefix of error messages (log lines keep fastmm-live:)
103 const LiveStrategy* strategy = nullptr; // nullptr: [strategy] name from the registry
104 // Called by the control thread every 50 ms; must not block. A non-empty result stops the session
105 // like SIGTERM (kill switch, cancel_all) with kExitSlowTier and is logged as the cause.
106 std::function<std::string()> watchdog;
107 // Before the session starts its threads, set every thread of the process to the CPUs not listed
108 // in [engine] cpu and net_cpus (confine_threads, live/thread_affinity.hpp).
110 false; // Attach to the fastmm-gateway listening here instead of connecting to the venues
111 // (live/gateway.hpp): its instrument table, its rings, no venue keys in this process, and no
112 // cancel_all on shutdown (the gateway cancels when the attachment closes).
113 std::string gateway_path;
114};
116// Process exit codes (listed in fastmm-live --help and docs/how-to/operations/). A failed
117// cancel-all wins over every other outcome: orders may still be resting.
118inline constexpr int kExitOk = 0; // --duration elapsed or SIGINT/SIGTERM, cancel_all ok
119inline constexpr int kExitUsage = 2; // bad command line, missing API keys
120inline constexpr int kExitConfig = 3; // bad config, strategy or parameters
121inline constexpr int kExitVenue = 4; // venue reference data failed
122inline constexpr int kExitRuntime = 5; // cancel_all failed, journal, ring overflow, uncaught error
123inline constexpr int kExitKilled = 6; // engine-tripped kill switch with [engine] on_kill = "exit"
124inline constexpr int kExitSlowTier = 7; // LiveOptions::watchdog (a Python slow tier failed)
125// Another process holds the instance lock, or a takeover failed; nothing was traded.
126inline constexpr int kExitLocked = 8;
127
128// How often a session that stays up after a kill ([engine] on_kill = "stay") repeats its ERROR.
129inline constexpr std::int64_t kKilledReminderNs = 10'000'000'000;
130
131// Runs one session; returns the process exit code. `cfg` must already have its venue secrets
132// resolved (or cleared for dry-run) and any command-line overrides applied: the journal embeds
133// cfg.effective_toml() and hashes it.
134int run_live(const Config& cfg, const LiveOptions& opts);
135
136// Resolves ${VAR} in every venue string. With `dry_run`, an unset variable in api_key or api_secret
137// clears the key; anything else unset, or a venue without keys outside a dry run, prints an error
138// prefixed with `prog` to stderr and returns false (kExitUsage).
139bool resolve_venue_env(Config& cfg, bool dry_run, const char* prog);
140
141// Restores the SIGINT/SIGTERM handlers run_live replaced; a no-op when none are replaced. For a
142// child forked during a session, whose control thread does not exist.
143void restore_signal_handlers() noexcept;
144
145} // namespace fastmm::live
Definition config.hpp:302
Definition params.hpp:102
Typed configuration (8.7).
Definition session.hpp:50
constexpr int kExitKilled
engine-tripped kill switch with [engine] on_kill = "exit"
Definition session.hpp:125
constexpr int kExitSlowTier
LiveOptions::watchdog (a Python slow tier failed)
Definition session.hpp:126
constexpr int kExitVenue
venue reference data failed
Definition session.hpp:123
constexpr int kExitUsage
bad command line, missing API keys
Definition session.hpp:121
constexpr int kExitRuntime
cancel_all failed, journal, ring overflow, uncaught error
Definition session.hpp:124
constexpr std::int64_t kKilledReminderNs
How often a session that stays up after a kill ([engine] on_kill = "stay") repeats its ERROR.
Definition session.hpp:131
bool resolve_venue_env(Config &cfg, bool dry_run, const char *prog)
Resolves ${VAR} in every venue string.
constexpr int kExitLocked
Another process holds the instance lock, or a takeover failed; nothing was traded.
Definition session.hpp:128
constexpr int kExitOk
Process exit codes (listed in fastmm-live --help and docs/how-to/operations/).
Definition session.hpp:120
void restore_signal_handlers() noexcept
Restores the SIGINT/SIGTERM handlers run_live replaced; a no-op when none are replaced.
int run_live(const Config &cfg, const LiveOptions &opts)
Runs one session; returns the process exit code.
constexpr int kExitConfig
bad config, strategy or parameters
Definition session.hpp:122
Definition strategy.hpp:16
Strongly typed identifiers.
Everything a factory needs that is backend-independent.
Definition registry.hpp:51
Definition session.hpp:77
std::function< std::string()> watchdog
Called by the control thread every 50 ms; must not block.
Definition session.hpp:108
bool no_control
Definition session.hpp:88
std::string journal_path
overrides [engine] journal_dir
Definition session.hpp:82
bool no_status
Definition session.hpp:85
bool confine_other_threads
Before the session starts its threads, set every thread of the process to the CPUs not listed in [eng...
Definition session.hpp:111
bool standby
Waits for the instance lock (live/instance_lock.hpp) instead of refusing to start while another proce...
Definition session.hpp:100
std::string config_path
Definition session.hpp:78
std::string program
prefix of error messages (log lines keep fastmm-live:)
Definition session.hpp:104
std::string gateway_path
(live/gateway.hpp): its instrument table, its rings, no venue keys in this process,...
Definition session.hpp:115
bool no_journal
Definition session.hpp:83
std::string control_path
Control socket (live/control_socket.hpp); empty takes <journal_dir>/<engine name>....
Definition session.hpp:87
std::string record_raw_dir
Definition session.hpp:81
bool dry_run
Definition session.hpp:80
const LiveStrategy * strategy
nullptr: [strategy] name from the registry
Definition session.hpp:105
bool takeover
standby, and once ready send handoff to the control socket of the session holding the lock; give up a...
Definition session.hpp:103
std::string status_path
overrides the default /dev/shm/fastmm-<engine>.status
Definition session.hpp:84
bool clear_kill
Removes the durable kill state before starting: clears a latched max-loss trip and arms the whole [ri...
Definition session.hpp:91
std::int64_t duration_ns
0 = until SIGINT/SIGTERM
Definition session.hpp:79
A strategy the caller builds instead of the registry's [strategy] name.
Definition session.hpp:53
std::string meta
the journal's strategy metadata (key=value lines)
Definition session.hpp:56
std::string name
journal header, status file and log lines
Definition session.hpp:54
std::function< std::string(const std::vector< std::pair< std::string, std::string > > &, InstrumentId)> set_params
The control socket's param: validates the (name, value) pairs against this strategy's schema and publ...
Definition session.hpp:74
std::function< std::unique_ptr< IEngineRunner >(RunnerDeps &deps)> make
Builds the runner on deps (deps.backend is a LiveBackend) on the calling thread, after the venues' re...
Definition session.hpp:66
const ParamSchema * params
the journal's parameter table
Definition session.hpp:55
std::function< void(std::function< void()> wake)> set_waker
Called with a function that wakes the engine, before the session's threads start, and with an empty o...
Definition session.hpp:62
std::function< void(IEngineRunner &runner)> finished
Called after the engine thread has stopped, before the runner is destroyed.
Definition session.hpp:68
std::vector< MsgRing * > inputs
Rings the engine polls besides the venues' (parameter updates); the caller keeps them alive.
Definition session.hpp:58