ff_script/functions/
scheduling.rs1use ff_core::contracts::*;
7use crate::error::ScriptError;
8use ff_core::keys::{ExecKeyContext, IndexKeys};
9use ff_core::types::*;
10
11use crate::result::{FcallResult, FromFcallResult};
12
13#[derive(Clone, Debug, PartialEq, Eq)]
15pub enum ChangePriorityResultPartial {
16 Changed,
17}
18
19impl ChangePriorityResultPartial {
20 pub fn complete(self, execution_id: ExecutionId) -> ChangePriorityResult {
21 match self {
22 Self::Changed => ChangePriorityResult::Changed { execution_id },
23 }
24 }
25}
26
27pub struct SchedOpKeys<'a> {
29 pub ctx: &'a ExecKeyContext,
30 pub idx: &'a IndexKeys,
31 pub lane_id: &'a LaneId,
32}
33
34ff_function! {
43 pub ff_issue_claim_grant(args: IssueClaimGrantArgs) -> IssueClaimGrantResult {
44 keys(k: &SchedOpKeys<'_>) {
45 k.ctx.core(),
46 k.ctx.claim_grant(),
47 k.idx.lane_eligible(k.lane_id),
48 }
49 argv {
50 args.execution_id.to_string(),
51 args.worker_id.to_string(),
52 args.worker_instance_id.to_string(),
53 args.lane_id.to_string(),
54 args.capability_hash.clone().unwrap_or_default(),
55 args.grant_ttl_ms.to_string(),
56 args.route_snapshot_json.clone().unwrap_or_default(),
57 args.admission_summary.clone().unwrap_or_default(),
58 args.worker_capabilities.iter().cloned().collect::<Vec<_>>().join(","),
60 }
61 }
62}
63
64impl FromFcallResult for IssueClaimGrantResult {
65 fn from_fcall_result(raw: &ferriskey::Value) -> Result<Self, ScriptError> {
66 let r = FcallResult::parse(raw)?.into_success()?;
67 let eid_str = r.field_str(0);
69 let eid = ExecutionId::parse(&eid_str)
70 .map_err(|e| ScriptError::Parse(format!("bad execution_id: {e}")))?;
71 Ok(IssueClaimGrantResult::Granted { execution_id: eid })
72 }
73}
74
75ff_function! {
81 pub ff_change_priority(args: ChangePriorityArgs) -> ChangePriorityResultPartial {
82 keys(k: &SchedOpKeys<'_>) {
83 k.ctx.core(),
84 k.idx.lane_eligible(k.lane_id),
85 }
86 argv {
87 args.execution_id.to_string(),
88 args.new_priority.to_string(),
89 }
90 }
91}
92
93impl FromFcallResult for ChangePriorityResultPartial {
94 fn from_fcall_result(raw: &ferriskey::Value) -> Result<Self, ScriptError> {
95 let _r = FcallResult::parse(raw)?.into_success()?;
96 Ok(Self::Changed)
98 }
99}
100
101ff_function! {
107 pub ff_update_progress(args: UpdateProgressArgs) -> UpdateProgressResult {
108 keys(k: &SchedOpKeys<'_>) {
109 k.ctx.core(),
110 }
111 argv {
112 args.execution_id.to_string(),
113 args.lease_id.to_string(),
114 args.lease_epoch.to_string(),
115 args.progress_pct.map(|p| p.to_string()).unwrap_or_default(),
116 args.progress_message.clone().unwrap_or_default(),
117 }
118 }
119}
120
121impl FromFcallResult for UpdateProgressResult {
122 fn from_fcall_result(raw: &ferriskey::Value) -> Result<Self, ScriptError> {
123 let _r = FcallResult::parse(raw)?.into_success()?;
124 Ok(UpdateProgressResult::Updated)
126 }
127}
128
129#[cfg(test)]
131mod partial_tests {
132 use super::*;
133 use ff_core::partition::PartitionConfig;
134
135 #[test]
136 fn change_priority_partial_complete_attaches_execution_id() {
137 let partial = ChangePriorityResultPartial::Changed;
138 let eid = ExecutionId::for_flow(&FlowId::new(), &PartitionConfig::default());
139 let full = partial.complete(eid.clone());
140 match full {
141 ChangePriorityResult::Changed { execution_id } => assert_eq!(execution_id, eid),
142 }
143 }
144}