byteflow/scheduler/
process.rs1use std::sync::atomic::{AtomicU64, Ordering};
2use std::sync::Arc;
3use std::time::Duration;
4
5use crate::bytecode::{Cap, CapRights, CapTarget, RevocationCell};
6use crate::vm::Vm;
7
8use super::mailbox::Mailbox;
9use super::oneshot;
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
24pub struct FlowId(pub(crate) u64);
25
26impl FlowId {
27 pub fn as_u64(self) -> u64 {
28 self.0
29 }
30}
31
32impl std::fmt::Display for FlowId {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 write!(f, "flow#{}", self.0)
35 }
36}
37
38static NEXT_FLOW_ID: AtomicU64 = AtomicU64::new(1);
39
40pub fn next_flow_id() -> FlowId {
41 FlowId(NEXT_FLOW_ID.fetch_add(1, Ordering::Relaxed))
42}
43
44#[derive(Clone, Copy, Debug, PartialEq, Eq)]
47pub enum RestartPolicy {
48 Always,
49 OnFailure,
50 Never,
51}
52
53#[derive(Debug, Default)]
56pub struct FlowMetrics {
57 pub instructions: AtomicU64,
58 pub messages_sent: AtomicU64,
60 pub messages_received: AtomicU64,
61 pub reschedules: AtomicU64,
62}
63
64pub struct Flow {
71 pub id: FlowId,
72 pub vm: Vm,
73 pub mailbox: Arc<Mailbox>,
74 pub metrics: Arc<FlowMetrics>,
75 pub restart_policy: RestartPolicy,
76 pub(crate) completion: oneshot::Sender<FlowOutcome>,
78 pub pending_message: Option<crate::bytecode::Value>,
80 pub last_receive_dest: Option<u8>,
82 pub(crate) pending_send: Option<PendingSend>,
84 pub(crate) supervisor: Option<super::supervisor::SupervisorLink>,
85 pub(crate) authority: Cap,
87 pub(crate) cell: Arc<RevocationCell>,
88 pub(crate) quota: Arc<super::quota::FlowQuota>,
89}
90
91#[derive(Debug, Clone, Copy)]
93pub(crate) enum PendingSend {
94 FireAndForget,
95 Ask {
96 dest_reg: u8,
97 expect_request_id: u64,
98 expect_sender: u64,
99 timeout: Option<Duration>,
100 },
101}
102
103#[derive(Clone, Debug, PartialEq)]
106pub enum FlowOutcome {
107 Completed(crate::bytecode::Value),
108 Failed(String),
109}
110
111impl Flow {
112 pub fn new(
113 id: FlowId,
114 vm: Vm,
115 mailbox: Arc<Mailbox>,
116 restart_policy: RestartPolicy,
117 completion: oneshot::Sender<FlowOutcome>,
118 ) -> Self {
119 let cell = Arc::new(RevocationCell::new());
120 let authority = Cap::root(
121 CapTarget::Flow(id.as_u64()),
122 CapRights::NONE,
123 None,
124 cell.as_ref(),
125 );
126 Self {
127 id,
128 vm,
129 mailbox,
130 metrics: Arc::new(FlowMetrics::default()),
131 restart_policy,
132 completion,
133 pending_message: None,
134 last_receive_dest: None,
135 pending_send: None,
136 supervisor: None,
137 authority,
138 cell,
139 quota: Arc::new(super::quota::FlowQuota::from_config(
140 super::quota::QuotaConfig::default(),
141 )),
142 }
143 }
144
145 pub(crate) fn complete(self, outcome: FlowOutcome) {
146 self.completion.send(outcome);
147 }
148}