ff_script/functions/
lease.rs1use ff_core::contracts::{
8 MarkLeaseExpiredArgs, MarkLeaseExpiredResult, RenewLeaseArgs, RenewLeaseResult,
9 RevokeLeaseArgs, RevokeLeaseResult,
10};
11use crate::error::ScriptError;
12use ff_core::keys::ExecKeyContext;
13use ff_core::types::TimestampMs;
14
15use crate::result::{FcallResult, FromFcallResult};
16
17impl FromFcallResult for RenewLeaseResult {
20 fn from_fcall_result(raw: &ferriskey::Value) -> Result<Self, ScriptError> {
21 let r = FcallResult::parse(raw)?.into_success()?;
22 let expires_str = r.field_str(0);
24 let expires_ms: i64 = expires_str
25 .parse()
26 .map_err(|_| ScriptError::Parse(format!("invalid expires_at: {expires_str}")))?;
27 Ok(RenewLeaseResult::Renewed {
28 expires_at: TimestampMs::from_millis(expires_ms),
29 })
30 }
31}
32
33impl FromFcallResult for MarkLeaseExpiredResult {
34 fn from_fcall_result(raw: &ferriskey::Value) -> Result<Self, ScriptError> {
35 let r = FcallResult::parse(raw)?.into_success()?;
36 match r.status.as_str() {
38 "OK" => Ok(MarkLeaseExpiredResult::MarkedExpired),
39 "ALREADY_SATISFIED" => Ok(MarkLeaseExpiredResult::AlreadySatisfied {
40 reason: r.field_str(0),
41 }),
42 other => Err(ScriptError::Parse(format!(
43 "unexpected status from ff_mark_lease_expired_if_due: {other}"
44 ))),
45 }
46 }
47}
48
49impl FromFcallResult for RevokeLeaseResult {
50 fn from_fcall_result(raw: &ferriskey::Value) -> Result<Self, ScriptError> {
51 let r = FcallResult::parse(raw)?.into_success()?;
52 match r.status.as_str() {
55 "OK" => {
56 Ok(RevokeLeaseResult::Revoked {
58 lease_id: r.field_str(1),
59 lease_epoch: r.field_str(2),
60 })
61 }
62 "ALREADY_SATISFIED" => Ok(RevokeLeaseResult::AlreadySatisfied {
63 reason: r.field_str(0),
64 }),
65 other => Err(ScriptError::Parse(format!(
66 "unexpected status from ff_revoke_lease: {other}"
67 ))),
68 }
69 }
70}
71
72ff_function! {
75 pub ff_renew_lease(args: RenewLeaseArgs) -> RenewLeaseResult {
81 keys(ctx: &ExecKeyContext) {
82 ctx.core(),
83 ctx.lease_current(),
84 ctx.lease_history(),
85 format!("ff:idx:{}:lease_expiry", ctx.hash_tag()),
86 }
87 argv {
88 args.execution_id.to_string(),
89 args.attempt_index.to_string(),
90 args.attempt_id.to_string(),
91 args.lease_id.to_string(),
92 args.lease_epoch.to_string(),
93 args.lease_ttl_ms.to_string(),
94 args.lease_history_grace_ms.to_string(),
95 }
96 }
97
98 pub ff_mark_lease_expired_if_due(args: MarkLeaseExpiredArgs) -> MarkLeaseExpiredResult {
104 keys(ctx: &ExecKeyContext) {
105 ctx.core(),
106 ctx.lease_current(),
107 format!("ff:idx:{}:lease_expiry", ctx.hash_tag()),
108 ctx.lease_history(),
109 }
110 argv {
111 args.execution_id.to_string(),
112 }
113 }
114
115 pub ff_revoke_lease(args: RevokeLeaseArgs) -> RevokeLeaseResult {
120 keys(ctx: &ExecKeyContext) {
121 ctx.core(),
122 ctx.lease_current(),
123 ctx.lease_history(),
124 format!("ff:idx:{}:lease_expiry", ctx.hash_tag()),
125 format!("ff:idx:{}:worker:{}:leases", ctx.hash_tag(), args.worker_instance_id),
126 }
127 argv {
128 args.execution_id.to_string(),
129 args.expected_lease_id.as_deref().unwrap_or("").to_string(),
130 args.reason.clone(),
131 }
132 }
133}