diff --git a/src/main.rs b/src/main.rs index 55c61c424b1cfdb55c8936e0078a18a24fe4d512..1cfdc2886b048d4520fba96b03dc463fe1b11644 100644 --- a/src/main.rs +++ b/src/main.rs @@ -97,10 +97,12 @@ fn picolib_setup(args: &args::Run) { tlua::function2( |x: String, opts: Option<ProposeEvalOpts>| -> Result<(), Error> { let timeout = opts.and_then(|opts| opts.timeout).unwrap_or(10.0); - traft::node::global()?.propose( - traft::Op::EvalLua { code: x }, - Duration::from_secs_f64(timeout), - ) + traft::node::global()? + .propose( + traft::OpEvalLua { code: x }, + Duration::from_secs_f64(timeout), + ) + .and_then(|res| res.map_err(Into::into)) }, ), ); diff --git a/src/tarantool.rs b/src/tarantool.rs index db6beefde0f14744342628d806983c17581299ef..c3cf4d5d141bad36050eeb43cc7b7b156820c659 100644 --- a/src/tarantool.rs +++ b/src/tarantool.rs @@ -5,7 +5,7 @@ use std::time::Instant; use ::tarantool::fiber; use ::tarantool::lua_state; use ::tarantool::net_box; -use ::tarantool::tlua::{self, LuaFunction, LuaTable}; +use ::tarantool::tlua::{self, LuaError, LuaFunction, LuaTable}; pub use ::tarantool::trigger::on_shutdown; use ::tarantool::tuple::AsTuple; @@ -163,9 +163,9 @@ pub fn set_cfg(cfg: &Cfg) { } #[track_caller] -pub fn eval(code: &str) { +pub fn eval(code: &str) -> Result<(), LuaError> { let l = lua_state(); - l.exec(code).unwrap() + l.exec(code) } // fn net_box_repeat_call_until_succeed<Args, Res, Addr>( diff --git a/src/traft/error.rs b/src/traft/error.rs index 80305c59c0b8baa374387f17cfbb754eb1e56dac..1d6a686a63e536a96afdb8515446d05c6a72fd51 100644 --- a/src/traft/error.rs +++ b/src/traft/error.rs @@ -1,4 +1,5 @@ use crate::traft::RaftId; +use ::tarantool::tlua::LuaError; use raft::StorageError; use rmp_serde::decode::Error as RmpDecodeError; use thiserror::Error; @@ -21,6 +22,8 @@ pub enum Error { instance_cluster_id: String, cluster_cluster_id: String, }, + #[error("error during execution of lua code: {0}")] + Lua(#[from] LuaError), } #[derive(Debug, Error)] diff --git a/src/traft/mod.rs b/src/traft/mod.rs index 008234af4e6287602d686c4f2d731a183053f301..c4c961dca6a364ae899dddbb45e286bb22b9f76e 100644 --- a/src/traft/mod.rs +++ b/src/traft/mod.rs @@ -12,6 +12,7 @@ pub mod topology; use crate::stringify_debug; use crate::util::Uppercase; use ::raft::prelude as raft; +use ::tarantool::tlua::LuaError; use ::tarantool::tuple::AsTuple; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; @@ -77,9 +78,7 @@ pub enum Op { msg: String, }, /// Evaluate the code on every instance in cluster. - EvalLua { - code: String, - }, + EvalLua(OpEvalLua), /// ReturnOne(OpReturnOne), PersistPeer { @@ -97,7 +96,7 @@ impl std::fmt::Display for Op { match self { Self::Nop => f.write_str("Nop"), Self::Info { msg } => write!(f, "Info({msg:?})"), - Self::EvalLua { code } => write!(f, "EvalLua({code:?})"), + Self::EvalLua(OpEvalLua { code }) => write!(f, "EvalLua({code:?})"), Self::ReturnOne(_) => write!(f, "ReturnOne"), Self::PersistPeer { peer } => { write!(f, "PersistPeer{}", peer) @@ -117,10 +116,7 @@ impl Op { crate::tlog!(Info, "{msg}"); Box::new(()) } - Self::EvalLua { code } => { - crate::tarantool::eval(code); - Box::new(()) - } + Self::EvalLua(op) => Box::new(op.result()), Self::ReturnOne(op) => Box::new(op.result()), Self::PersistPeer { peer } => { Storage::persist_peer(peer).unwrap(); @@ -155,6 +151,24 @@ impl OpResult for OpReturnOne { } } +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub struct OpEvalLua { + pub code: String, +} + +impl OpResult for OpEvalLua { + type Result = Result<(), LuaError>; + fn result(&self) -> Self::Result { + crate::tarantool::eval(&self.code) + } +} + +impl From<OpEvalLua> for Op { + fn from(op: OpEvalLua) -> Op { + Op::EvalLua(op) + } +} + pub trait OpResult { type Result: 'static; fn result(&self) -> Self::Result;