From 61e65b7bbd6bec8a19f3af804c191acf9832d8bc Mon Sep 17 00:00:00 2001 From: Adriano Santos Date: Mon, 13 Feb 2023 18:03:00 -0300 Subject: [PATCH] Rust I Love u and Hate u --- Cargo.lock | 123 +++- spawn-examples/Cargo.toml | 1 + spawn-examples/src/joe.rs | 14 +- spawn-examples/src/main.rs | 3 + spawn-rs/Cargo.toml | 2 + spawn-rs/build.rs | 2 +- spawn-rs/proto/actor.proto | 2 +- spawn-rs/proto/protocol.proto | 24 +- spawn-rs/src/action.rs | 35 +- ...gr.functions.protocol.rs => eigr.spawn.rs} | 240 ++++++- .../src/eigr/{spawn => }/google.protobuf.rs | 0 spawn-rs/src/eigr/mod.rs | 1 + spawn-rs/src/eigr/spawn.rs | 592 ++++++++++++++++++ .../spawn/eigr.functions.protocol.actors.rs | 218 ------- spawn-rs/src/eigr/spawn/eigr.spawn.rs | 278 -------- spawn-rs/src/handler/callback.rs | 15 +- spawn-rs/src/lib.rs | 40 +- spawn-rs/src/serializer.rs | 12 + spawn-rs/src/spawn.rs | 10 +- 19 files changed, 1043 insertions(+), 569 deletions(-) rename spawn-rs/src/eigr/{spawn/eigr.functions.protocol.rs => eigr.spawn.rs} (62%) rename spawn-rs/src/eigr/{spawn => }/google.protobuf.rs (100%) create mode 100644 spawn-rs/src/eigr/mod.rs create mode 100644 spawn-rs/src/eigr/spawn.rs delete mode 100644 spawn-rs/src/eigr/spawn/eigr.functions.protocol.actors.rs delete mode 100644 spawn-rs/src/eigr/spawn/eigr.spawn.rs create mode 100644 spawn-rs/src/serializer.rs diff --git a/Cargo.lock b/Cargo.lock index a4144ed..0903614 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,6 +68,18 @@ dependencies = [ "syn", ] +[[package]] +name = "actix-protobuf" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e1151cdf1d5f30115da7c8e3e4cefadfb6d396973d75354647c4e8fae3a14f" +dependencies = [ + "actix-web", + "derive_more", + "futures-util", + "prost", +] + [[package]] name = "actix-router" version = "0.5.1" @@ -391,6 +403,40 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fastrand" version = "1.8.0" @@ -522,6 +568,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "http" version = "0.2.8" @@ -545,6 +597,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "idna" version = "0.3.0" @@ -574,6 +632,28 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +dependencies = [ + "libc", + "windows-sys 0.45.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.45.0", +] + [[package]] name = "itertools" version = "0.10.5" @@ -616,6 +696,12 @@ version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "local-channel" version = "0.1.3" @@ -698,7 +784,7 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -934,6 +1020,20 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.36.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.45.0", +] + [[package]] name = "ryu" version = "1.0.12" @@ -1030,6 +1130,7 @@ dependencies = [ name = "spawn-examples" version = "0.1.0" dependencies = [ + "env_logger", "prost-types", "spawn-rs", "tokio", @@ -1039,8 +1140,10 @@ dependencies = [ name = "spawn-rs" version = "0.1.0" dependencies = [ + "actix-protobuf", "actix-server", "actix-web", + "env_logger", "prost", "prost-types", "tonic-build", @@ -1071,6 +1174,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + [[package]] name = "time" version = "0.3.17" @@ -1269,6 +1381,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/spawn-examples/Cargo.toml b/spawn-examples/Cargo.toml index 5bae9b8..3c2207a 100644 --- a/spawn-examples/Cargo.toml +++ b/spawn-examples/Cargo.toml @@ -4,6 +4,7 @@ name = "spawn-examples" version = "0.1.0" [dependencies] +env_logger = "0.10.0" prost-types = "0.11" spawn-rs = {path = "../spawn-rs"} tokio = {version = "1.25.0", features = ["full"]} diff --git a/spawn-examples/src/joe.rs b/spawn-examples/src/joe.rs index d56598c..9372ab5 100644 --- a/spawn-examples/src/joe.rs +++ b/spawn-examples/src/joe.rs @@ -1,14 +1,26 @@ use prost_types::Any; use spawn_rs::{ - action::{Action, Message}, + action::Action, actor::{Actor, ActorSettings, Kind}, context::Context, + serializer::Serializer, value::Value, + Message, }; pub struct Joe; +impl Serializer for Joe { + fn decode(&mut self, _msg: prost_types::Any) -> Box { + todo!() + } + + fn encode(&mut self, _msg: Box) -> prost_types::Any { + todo!() + } +} + impl Actor for Joe { fn settings(&mut self) -> ActorSettings { ActorSettings::new() diff --git a/spawn-examples/src/main.rs b/spawn-examples/src/main.rs index 0a5a66f..6141be9 100644 --- a/spawn-examples/src/main.rs +++ b/spawn-examples/src/main.rs @@ -1,3 +1,4 @@ +extern crate env_logger; extern crate prost_types; extern crate tokio; @@ -7,6 +8,8 @@ use spawn_rs::spawn::Spawn; #[tokio::main] async fn main() { + env_logger::init_from_env(env_logger::Env::new().default_filter_or("debug")); + Spawn::new() .system("spawn-system".to_string()) .port(8091) diff --git a/spawn-rs/Cargo.toml b/spawn-rs/Cargo.toml index 4df838a..1692949 100644 --- a/spawn-rs/Cargo.toml +++ b/spawn-rs/Cargo.toml @@ -14,8 +14,10 @@ name = "spawn-rs" version = "0.1.0" [dependencies] +actix-protobuf = "0.9.0" actix-server = "2.2.0" actix-web = "4" +env_logger = "0.10.0" prost = "0.11" prost-types = "0.11" diff --git a/spawn-rs/build.rs b/spawn-rs/build.rs index 0afda65..f80d0f6 100644 --- a/spawn-rs/build.rs +++ b/spawn-rs/build.rs @@ -1,7 +1,7 @@ fn main() -> Result<(), Box> { tonic_build::configure() .build_server(false) - .out_dir("src/eigr/spawn") + .out_dir("src/eigr") .compile( &[ "proto/google/protobuf/any.proto", diff --git a/spawn-rs/proto/actor.proto b/spawn-rs/proto/actor.proto index d7a0846..acfc094 100644 --- a/spawn-rs/proto/actor.proto +++ b/spawn-rs/proto/actor.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package eigr.functions.protocol.actors; +package eigr.spawn; import "google/protobuf/any.proto"; diff --git a/spawn-rs/proto/protocol.proto b/spawn-rs/proto/protocol.proto index 046f2e4..f0d6823 100644 --- a/spawn-rs/proto/protocol.proto +++ b/spawn-rs/proto/protocol.proto @@ -154,7 +154,7 @@ // syntax = "proto3"; -package eigr.functions.protocol; +package eigr.spawn; import "actor.proto"; import "google/protobuf/any.proto"; @@ -180,10 +180,10 @@ message Context { map tags = 5; // Who is calling target actor - eigr.functions.protocol.actors.ActorId caller = 2; + eigr.spawn.ActorId caller = 2; // The target actor itself - eigr.functions.protocol.actors.ActorId self = 3; + eigr.spawn.ActorId self = 3; } // Noop is used when the input or output value of a function or method @@ -196,7 +196,7 @@ message RegistrationRequest { ServiceInfo service_info = 1; - eigr.functions.protocol.actors.ActorSystem actor_system = 2; + eigr.spawn.ActorSystem actor_system = 2; } message RegistrationResponse { @@ -233,7 +233,7 @@ message ServiceInfo { } message SpawnRequest { - repeated eigr.functions.protocol.actors.ActorId actors = 1; + repeated eigr.spawn.ActorId actors = 1; } message SpawnResponse { @@ -330,9 +330,9 @@ message Workflow { // * metadata: Meta information or headers message InvocationRequest { - eigr.functions.protocol.actors.ActorSystem system = 1; + eigr.spawn.ActorSystem system = 1; - eigr.functions.protocol.actors.Actor actor = 2; + eigr.spawn.Actor actor = 2; string command_name = 3; @@ -343,7 +343,7 @@ message InvocationRequest { bool async = 5; - eigr.functions.protocol.actors.ActorId caller = 6; + eigr.spawn.ActorId caller = 6; map metadata = 8; @@ -365,7 +365,7 @@ message InvocationRequest { // * payload: The value to be passed to the function or method corresponding to command_name. message ActorInvocation { - eigr.functions.protocol.actors.ActorId actor = 1; + eigr.spawn.ActorId actor = 1; string command_name = 2; @@ -376,7 +376,7 @@ message ActorInvocation { Noop noop = 5; } - eigr.functions.protocol.actors.ActorId caller = 6; + eigr.spawn.ActorId caller = 6; } // The user function's response after executing the action originated by the local proxy request via ActorInvocation. @@ -415,9 +415,9 @@ message InvocationResponse { RequestStatus status = 1; - eigr.functions.protocol.actors.ActorSystem system = 2; + eigr.spawn.ActorSystem system = 2; - eigr.functions.protocol.actors.Actor actor = 3; + eigr.spawn.Actor actor = 3; oneof payload { google.protobuf.Any value = 4; diff --git a/spawn-rs/src/action.rs b/spawn-rs/src/action.rs index 11901fb..30d1aea 100644 --- a/spawn-rs/src/action.rs +++ b/spawn-rs/src/action.rs @@ -1,35 +1,4 @@ -use prost_types::Any; - -use crate::{actor::Actor, context::Context, value::Value}; - -#[derive(Debug, Clone)] -pub struct Message { - action: String, - body: Any, -} - -impl Default for Message { - fn default() -> Message { - Message { - action: String::from(""), - body: Any::default(), - } - } -} - -impl Message { - pub fn new() -> Self { - Default::default() - } - - pub fn action(&self) -> &str { - &self.action - } - - pub fn body(&self) -> &Any { - &self.body - } -} +use crate::{actor::Actor, context::Context, value::Value, Message}; #[allow(unused_variables)] pub trait Action @@ -37,5 +6,5 @@ where Self: Actor, { /// This method is called for every message received by this actor. - fn handle(&mut self, req: Message, ctx: &mut Context) -> Value; + fn handle(&mut self, msg: Message, ctx: &mut Context) -> Value; } diff --git a/spawn-rs/src/eigr/spawn/eigr.functions.protocol.rs b/spawn-rs/src/eigr/eigr.spawn.rs similarity index 62% rename from spawn-rs/src/eigr/spawn/eigr.functions.protocol.rs rename to spawn-rs/src/eigr/eigr.spawn.rs index 90915b5..39fa9c4 100644 --- a/spawn-rs/src/eigr/spawn/eigr.functions.protocol.rs +++ b/spawn-rs/src/eigr/eigr.spawn.rs @@ -1,3 +1,221 @@ +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Registry { + #[prost(map = "string, message", tag = "1")] + pub actors: ::std::collections::HashMap<::prost::alloc::string::String, Actor>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorSystem { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag = "2")] + pub registry: ::core::option::Option, +} +/// A strategy for save state. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorSnapshotStrategy { + #[prost(oneof = "actor_snapshot_strategy::Strategy", tags = "1")] + pub strategy: ::core::option::Option, +} +/// Nested message and enum types in `ActorSnapshotStrategy`. +pub mod actor_snapshot_strategy { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Strategy { + /// the timeout strategy. + #[prost(message, tag = "1")] + Timeout(super::TimeoutStrategy), + } +} +/// A strategy which a user function's entity is passivated. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorDeactivationStrategy { + #[prost(oneof = "actor_deactivation_strategy::Strategy", tags = "1")] + pub strategy: ::core::option::Option, +} +/// Nested message and enum types in `ActorDeactivationStrategy`. +pub mod actor_deactivation_strategy { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Strategy { + /// the timeout strategy. + #[prost(message, tag = "1")] + Timeout(super::TimeoutStrategy), + } +} +/// A strategy based on a timeout. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TimeoutStrategy { + /// The timeout in millis + #[prost(int64, tag = "1")] + pub timeout: i64, +} +/// A command represents an action that the user can perform on an Actor. +/// Commands in supporting languages are represented by functions or methods. +/// An Actor command has nothing to do with the semantics of Commands in a CQRS/EventSourced system. +/// It just represents an action that supporting languages can invoke. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Command { + /// The name of the function or method in the supporting language that has been registered in Ator. + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, +} +/// A FixedTimerCommand is similar to a regular Command, its main differences are that it is scheduled to run at regular intervals +/// and only takes the actor's state as an argument. +/// Timer Commands are good for executing loops that manipulate the actor's own state. +/// In Elixir or other languages in BEAM it would be similar to invoking Process.send_after(self(), atom, msg, timeout) +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct FixedTimerCommand { + /// The time to wait until the command is triggered + #[prost(int32, tag = "1")] + pub seconds: i32, + /// See Command description Above + #[prost(message, optional, tag = "2")] + pub command: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorState { + #[prost(map = "string, string", tag = "1")] + pub tags: ::std::collections::HashMap< + ::prost::alloc::string::String, + ::prost::alloc::string::String, + >, + #[prost(message, optional, tag = "2")] + pub state: ::core::option::Option<::prost_types::Any>, +} +/// TODO doc here +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Metadata { + /// A channel group represents a way to send commands to various actors + /// that belong to a certain semantic group. + #[prost(string, tag = "1")] + pub channel_group: ::prost::alloc::string::String, + #[prost(map = "string, string", tag = "2")] + pub tags: ::std::collections::HashMap< + ::prost::alloc::string::String, + ::prost::alloc::string::String, + >, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorSettings { + /// Indicates the type of Actor to be configured. + #[prost(enumeration = "Kind", tag = "1")] + pub kind: i32, + /// Indicates whether an actor's state should be persisted in a definitive store. + #[prost(bool, tag = "2")] + pub stateful: bool, + /// Snapshot strategy + #[prost(message, optional, tag = "3")] + pub snapshot_strategy: ::core::option::Option, + /// Deactivate strategy + #[prost(message, optional, tag = "4")] + pub deactivation_strategy: ::core::option::Option, + /// When kind is POOLED this is used to define minimun actor instances + #[prost(int32, tag = "5")] + pub min_pool_size: i32, + /// When kind is POOLED this is used to define maximum actor instances + #[prost(int32, tag = "6")] + pub max_pool_size: i32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorId { + /// The name of a Actor Entity. + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + /// Name of a ActorSystem + #[prost(string, tag = "2")] + pub system: ::prost::alloc::string::String, + /// When the Actor is of the Abstract type, + /// the name of the parent Actor must be informed here. + #[prost(string, tag = "3")] + pub parent: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Actor { + /// Actor Identification + #[prost(message, optional, tag = "1")] + pub id: ::core::option::Option, + /// A Actor state. + #[prost(message, optional, tag = "2")] + pub state: ::core::option::Option, + /// Actor metadata + #[prost(message, optional, tag = "6")] + pub metadata: ::core::option::Option, + /// Actor settings. + #[prost(message, optional, tag = "3")] + pub settings: ::core::option::Option, + /// The commands registered for an actor + #[prost(message, repeated, tag = "4")] + pub commands: ::prost::alloc::vec::Vec, + /// The registered timer commands for an actor. + #[prost(message, repeated, tag = "5")] + pub timer_commands: ::prost::alloc::vec::Vec, +} +/// The type that defines the runtime characteristics of the Actor. +/// Regardless of the type of actor it is important that +/// all actors are registered during the proxy and host initialization phase. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum Kind { + /// When no type is informed, the default to be assumed will be the Singleton pattern. + UnknowKind = 0, + /// Abstract actors are used to create children of this based actor at runtime + Abstract = 1, + /// Singleton actors as the name suggests have only one real instance of themselves running + /// during their entire lifecycle. That is, they are the opposite of the Abstract type Actors. + Singleton = 2, + /// Pooled Actors are similar to abstract actors, but unlike them, + /// their identifying name will always be the one registered at the system initialization stage. + /// The great advantage of Pooled actors is that they have multiple instances of themselves + /// acting as a request service pool. + /// Pooled actors are also stateless actors, that is, they will not have their + /// in-memory state persisted via Statesstore. This is done to avoid problems + /// with the correctness of the stored state. + /// Pooled Actors are generally used for tasks where the Actor Model would perform worse + /// than other concurrency models and for tasks that do not require state concerns. + /// Integration flows, data caching, proxies are good examples of use cases + /// for this type of Actor. + Pooled = 3, + /// Reserved for future use + Proxy = 4, +} +impl Kind { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Kind::UnknowKind => "UNKNOW_KIND", + Kind::Abstract => "ABSTRACT", + Kind::Singleton => "SINGLETON", + Kind::Pooled => "POOLED", + Kind::Proxy => "PROXY", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UNKNOW_KIND" => Some(Self::UnknowKind), + "ABSTRACT" => Some(Self::Abstract), + "SINGLETON" => Some(Self::Singleton), + "POOLED" => Some(Self::Pooled), + "PROXY" => Some(Self::Proxy), + _ => None, + } + } +} /// Context is where current and/or updated state is stored /// to be transmitted to/from proxy and user function /// @@ -24,10 +242,10 @@ pub struct Context { >, /// Who is calling target actor #[prost(message, optional, tag = "2")] - pub caller: ::core::option::Option, + pub caller: ::core::option::Option, /// The target actor itself #[prost(message, optional, tag = "3")] - pub self_: ::core::option::Option, + pub self_: ::core::option::Option, } /// Noop is used when the input or output value of a function or method /// does not matter to the caller of a Workflow or when the user just wants to receive @@ -42,7 +260,7 @@ pub struct RegistrationRequest { #[prost(message, optional, tag = "1")] pub service_info: ::core::option::Option, #[prost(message, optional, tag = "2")] - pub actor_system: ::core::option::Option, + pub actor_system: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -83,7 +301,7 @@ pub struct ServiceInfo { #[derive(Clone, PartialEq, ::prost::Message)] pub struct SpawnRequest { #[prost(message, repeated, tag = "1")] - pub actors: ::prost::alloc::vec::Vec, + pub actors: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -210,15 +428,15 @@ pub mod workflow { #[derive(Clone, PartialEq, ::prost::Message)] pub struct InvocationRequest { #[prost(message, optional, tag = "1")] - pub system: ::core::option::Option, + pub system: ::core::option::Option, #[prost(message, optional, tag = "2")] - pub actor: ::core::option::Option, + pub actor: ::core::option::Option, #[prost(string, tag = "3")] pub command_name: ::prost::alloc::string::String, #[prost(bool, tag = "5")] pub r#async: bool, #[prost(message, optional, tag = "6")] - pub caller: ::core::option::Option, + pub caller: ::core::option::Option, #[prost(map = "string, string", tag = "8")] pub metadata: ::std::collections::HashMap< ::prost::alloc::string::String, @@ -257,13 +475,13 @@ pub mod invocation_request { #[derive(Clone, PartialEq, ::prost::Message)] pub struct ActorInvocation { #[prost(message, optional, tag = "1")] - pub actor: ::core::option::Option, + pub actor: ::core::option::Option, #[prost(string, tag = "2")] pub command_name: ::prost::alloc::string::String, #[prost(message, optional, tag = "3")] pub current_context: ::core::option::Option, #[prost(message, optional, tag = "6")] - pub caller: ::core::option::Option, + pub caller: ::core::option::Option, #[prost(oneof = "actor_invocation::Payload", tags = "4, 5")] pub payload: ::core::option::Option, } @@ -325,9 +543,9 @@ pub struct InvocationResponse { #[prost(message, optional, tag = "1")] pub status: ::core::option::Option, #[prost(message, optional, tag = "2")] - pub system: ::core::option::Option, + pub system: ::core::option::Option, #[prost(message, optional, tag = "3")] - pub actor: ::core::option::Option, + pub actor: ::core::option::Option, #[prost(oneof = "invocation_response::Payload", tags = "4, 5")] pub payload: ::core::option::Option, } diff --git a/spawn-rs/src/eigr/spawn/google.protobuf.rs b/spawn-rs/src/eigr/google.protobuf.rs similarity index 100% rename from spawn-rs/src/eigr/spawn/google.protobuf.rs rename to spawn-rs/src/eigr/google.protobuf.rs diff --git a/spawn-rs/src/eigr/mod.rs b/spawn-rs/src/eigr/mod.rs new file mode 100644 index 0000000..e40b065 --- /dev/null +++ b/spawn-rs/src/eigr/mod.rs @@ -0,0 +1 @@ +pub mod spawn; diff --git a/spawn-rs/src/eigr/spawn.rs b/spawn-rs/src/eigr/spawn.rs new file mode 100644 index 0000000..b92cec8 --- /dev/null +++ b/spawn-rs/src/eigr/spawn.rs @@ -0,0 +1,592 @@ +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Registry { + #[prost(map = "string, message", tag = "1")] + pub actors: ::std::collections::HashMap<::prost::alloc::string::String, Actor>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorSystem { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag = "2")] + pub registry: ::core::option::Option, +} +/// A strategy for save state. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorSnapshotStrategy { + #[prost(oneof = "actor_snapshot_strategy::Strategy", tags = "1")] + pub strategy: ::core::option::Option, +} +/// Nested message and enum types in `ActorSnapshotStrategy`. +pub mod actor_snapshot_strategy { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Strategy { + /// the timeout strategy. + #[prost(message, tag = "1")] + Timeout(super::TimeoutStrategy), + } +} +/// A strategy which a user function's entity is passivated. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorDeactivationStrategy { + #[prost(oneof = "actor_deactivation_strategy::Strategy", tags = "1")] + pub strategy: ::core::option::Option, +} +/// Nested message and enum types in `ActorDeactivationStrategy`. +pub mod actor_deactivation_strategy { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Strategy { + /// the timeout strategy. + #[prost(message, tag = "1")] + Timeout(super::TimeoutStrategy), + } +} +/// A strategy based on a timeout. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TimeoutStrategy { + /// The timeout in millis + #[prost(int64, tag = "1")] + pub timeout: i64, +} +/// A command represents an action that the user can perform on an Actor. +/// Commands in supporting languages are represented by functions or methods. +/// An Actor command has nothing to do with the semantics of Commands in a CQRS/EventSourced system. +/// It just represents an action that supporting languages can invoke. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Command { + /// The name of the function or method in the supporting language that has been registered in Ator. + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, +} +/// A FixedTimerCommand is similar to a regular Command, its main differences are that it is scheduled to run at regular intervals +/// and only takes the actor's state as an argument. +/// Timer Commands are good for executing loops that manipulate the actor's own state. +/// In Elixir or other languages in BEAM it would be similar to invoking Process.send_after(self(), atom, msg, timeout) +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct FixedTimerCommand { + /// The time to wait until the command is triggered + #[prost(int32, tag = "1")] + pub seconds: i32, + /// See Command description Above + #[prost(message, optional, tag = "2")] + pub command: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorState { + #[prost(map = "string, string", tag = "1")] + pub tags: + ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + #[prost(message, optional, tag = "2")] + pub state: ::core::option::Option<::prost_types::Any>, +} +/// TODO doc here +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Metadata { + /// A channel group represents a way to send commands to various actors + /// that belong to a certain semantic group. + #[prost(string, tag = "1")] + pub channel_group: ::prost::alloc::string::String, + #[prost(map = "string, string", tag = "2")] + pub tags: + ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorSettings { + /// Indicates the type of Actor to be configured. + #[prost(enumeration = "Kind", tag = "1")] + pub kind: i32, + /// Indicates whether an actor's state should be persisted in a definitive store. + #[prost(bool, tag = "2")] + pub stateful: bool, + /// Snapshot strategy + #[prost(message, optional, tag = "3")] + pub snapshot_strategy: ::core::option::Option, + /// Deactivate strategy + #[prost(message, optional, tag = "4")] + pub deactivation_strategy: ::core::option::Option, + /// When kind is POOLED this is used to define minimun actor instances + #[prost(int32, tag = "5")] + pub min_pool_size: i32, + /// When kind is POOLED this is used to define maximum actor instances + #[prost(int32, tag = "6")] + pub max_pool_size: i32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorId { + /// The name of a Actor Entity. + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + /// Name of a ActorSystem + #[prost(string, tag = "2")] + pub system: ::prost::alloc::string::String, + /// When the Actor is of the Abstract type, + /// the name of the parent Actor must be informed here. + #[prost(string, tag = "3")] + pub parent: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Actor { + /// Actor Identification + #[prost(message, optional, tag = "1")] + pub id: ::core::option::Option, + /// A Actor state. + #[prost(message, optional, tag = "2")] + pub state: ::core::option::Option, + /// Actor metadata + #[prost(message, optional, tag = "6")] + pub metadata: ::core::option::Option, + /// Actor settings. + #[prost(message, optional, tag = "3")] + pub settings: ::core::option::Option, + /// The commands registered for an actor + #[prost(message, repeated, tag = "4")] + pub commands: ::prost::alloc::vec::Vec, + /// The registered timer commands for an actor. + #[prost(message, repeated, tag = "5")] + pub timer_commands: ::prost::alloc::vec::Vec, +} +/// The type that defines the runtime characteristics of the Actor. +/// Regardless of the type of actor it is important that +/// all actors are registered during the proxy and host initialization phase. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum Kind { + /// When no type is informed, the default to be assumed will be the Singleton pattern. + UnknowKind = 0, + /// Abstract actors are used to create children of this based actor at runtime + Abstract = 1, + /// Singleton actors as the name suggests have only one real instance of themselves running + /// during their entire lifecycle. That is, they are the opposite of the Abstract type Actors. + Singleton = 2, + /// Pooled Actors are similar to abstract actors, but unlike them, + /// their identifying name will always be the one registered at the system initialization stage. + /// The great advantage of Pooled actors is that they have multiple instances of themselves + /// acting as a request service pool. + /// Pooled actors are also stateless actors, that is, they will not have their + /// in-memory state persisted via Statesstore. This is done to avoid problems + /// with the correctness of the stored state. + /// Pooled Actors are generally used for tasks where the Actor Model would perform worse + /// than other concurrency models and for tasks that do not require state concerns. + /// Integration flows, data caching, proxies are good examples of use cases + /// for this type of Actor. + Pooled = 3, + /// Reserved for future use + Proxy = 4, +} +impl Kind { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Kind::UnknowKind => "UNKNOW_KIND", + Kind::Abstract => "ABSTRACT", + Kind::Singleton => "SINGLETON", + Kind::Pooled => "POOLED", + Kind::Proxy => "PROXY", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UNKNOW_KIND" => Some(Self::UnknowKind), + "ABSTRACT" => Some(Self::Abstract), + "SINGLETON" => Some(Self::Singleton), + "POOLED" => Some(Self::Pooled), + "PROXY" => Some(Self::Proxy), + _ => None, + } + } +} +/// Context is where current and/or updated state is stored +/// to be transmitted to/from proxy and user function +/// +/// Params: +/// * state: Actor state passed back and forth between proxy and user function. +/// * metadata: Meta information that comes in invocations +/// * tags: Meta information stored in the actor +/// * caller: ActorId of who is calling target actor +/// * self: ActorId of itself +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Context { + #[prost(message, optional, tag = "1")] + pub state: ::core::option::Option<::prost_types::Any>, + #[prost(map = "string, string", tag = "4")] + pub metadata: + ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + #[prost(map = "string, string", tag = "5")] + pub tags: + ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + /// Who is calling target actor + #[prost(message, optional, tag = "2")] + pub caller: ::core::option::Option, + /// The target actor itself + #[prost(message, optional, tag = "3")] + pub self_: ::core::option::Option, +} +/// Noop is used when the input or output value of a function or method +/// does not matter to the caller of a Workflow or when the user just wants to receive +/// the Context in the request, that is, +/// he does not care about the input value only with the state. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Noop {} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RegistrationRequest { + #[prost(message, optional, tag = "1")] + pub service_info: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub actor_system: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RegistrationResponse { + #[prost(message, optional, tag = "1")] + pub status: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub proxy_info: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ServiceInfo { + /// The name of the actor system, eg, "my-actor-system". + #[prost(string, tag = "1")] + pub service_name: ::prost::alloc::string::String, + /// The version of the service. + #[prost(string, tag = "2")] + pub service_version: ::prost::alloc::string::String, + /// A description of the runtime for the service. Can be anything, but examples might be: + /// - node v10.15.2 + /// - OpenJDK Runtime Environment 1.8.0_192-b12 + #[prost(string, tag = "3")] + pub service_runtime: ::prost::alloc::string::String, + /// If using a support library, the name of that library, eg "spawn-jvm" + #[prost(string, tag = "4")] + pub support_library_name: ::prost::alloc::string::String, + /// The version of the support library being used. + #[prost(string, tag = "5")] + pub support_library_version: ::prost::alloc::string::String, + /// Spawn protocol major version accepted by the support library. + #[prost(int32, tag = "6")] + pub protocol_major_version: i32, + /// Spawn protocol minor version accepted by the support library. + #[prost(int32, tag = "7")] + pub protocol_minor_version: i32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SpawnRequest { + #[prost(message, repeated, tag = "1")] + pub actors: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SpawnResponse { + #[prost(message, optional, tag = "1")] + pub status: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProxyInfo { + #[prost(int32, tag = "1")] + pub protocol_major_version: i32, + #[prost(int32, tag = "2")] + pub protocol_minor_version: i32, + #[prost(string, tag = "3")] + pub proxy_name: ::prost::alloc::string::String, + #[prost(string, tag = "4")] + pub proxy_version: ::prost::alloc::string::String, +} +/// When a Host Function is invoked it returns the updated state and return value to the call. +/// It can also return a number of side effects to other Actors as a result of its computation. +/// These side effects will be forwarded to the respective Actors asynchronously and should not affect the Host Function's response to its caller. +/// Internally side effects is just a special kind of InvocationRequest. +/// Useful for handle handle `recipient list` and `Composed Message Processor` patterns: +/// +/// +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SideEffect { + #[prost(message, optional, tag = "1")] + pub request: ::core::option::Option, +} +/// Broadcast a message to many Actors +/// Useful for handle `recipient list`, `publish-subscribe channel`, and `scatter-gatther` patterns: +/// +/// +/// +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Broadcast { + /// Channel of target Actors + #[prost(string, tag = "1")] + pub channel_group: ::prost::alloc::string::String, + /// Command. Only Actors that have this command will run successfully + #[prost(string, tag = "2")] + pub command_name: ::prost::alloc::string::String, + /// Payload + #[prost(oneof = "broadcast::Payload", tags = "3, 4")] + pub payload: ::core::option::Option, +} +/// Nested message and enum types in `Broadcast`. +pub mod broadcast { + /// Payload + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Payload { + #[prost(message, tag = "3")] + Value(::prost_types::Any), + #[prost(message, tag = "4")] + Noop(super::Noop), + } +} +/// Sends the output of a command of an Actor to the input of another command of an Actor +/// Useful for handle `pipes` pattern: +/// +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Pipe { + /// Target Actor + #[prost(string, tag = "1")] + pub actor: ::prost::alloc::string::String, + /// Command. + #[prost(string, tag = "2")] + pub command_name: ::prost::alloc::string::String, +} +/// Sends the input of a command of an Actor to the input of another command of an Actor +/// Useful for handle `content-basead router` pattern +/// +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Forward { + /// Target Actor + #[prost(string, tag = "1")] + pub actor: ::prost::alloc::string::String, + /// Command. + #[prost(string, tag = "2")] + pub command_name: ::prost::alloc::string::String, +} +/// Container for archicetural message patterns +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Workflow { + #[prost(message, optional, tag = "2")] + pub broadcast: ::core::option::Option, + #[prost(message, repeated, tag = "1")] + pub effects: ::prost::alloc::vec::Vec, + #[prost(oneof = "workflow::Routing", tags = "3, 4")] + pub routing: ::core::option::Option, +} +/// Nested message and enum types in `Workflow`. +pub mod workflow { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Routing { + #[prost(message, tag = "3")] + Pipe(super::Pipe), + #[prost(message, tag = "4")] + Forward(super::Forward), + } +} +/// The user function when it wants to send a message to an Actor uses the InvocationRequest message type. +/// +/// Params: +/// * system: See ActorSystem message. +/// * actor: The target Actor, i.e. the one that the user function is calling to perform some computation. +/// * caller: The caller Actor +/// * command_name: The function or method on the target Actor that will receive this request +/// and perform some useful computation with the sent data. +/// * value: This is the value sent by the user function to be computed by the request's target Actor command. +/// * async: Indicates whether the command should be processed synchronously, where a response should be sent back to the user function, +/// or whether the command should be processed asynchronously, i.e. no response sent to the caller and no waiting. +/// * metadata: Meta information or headers +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct InvocationRequest { + #[prost(message, optional, tag = "1")] + pub system: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub actor: ::core::option::Option, + #[prost(string, tag = "3")] + pub command_name: ::prost::alloc::string::String, + #[prost(bool, tag = "5")] + pub r#async: bool, + #[prost(message, optional, tag = "6")] + pub caller: ::core::option::Option, + #[prost(map = "string, string", tag = "8")] + pub metadata: + ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + #[prost(int64, tag = "9")] + pub scheduled_to: i64, + #[prost(bool, tag = "10")] + pub pooled: bool, + #[prost(oneof = "invocation_request::Payload", tags = "4, 7")] + pub payload: ::core::option::Option, +} +/// Nested message and enum types in `InvocationRequest`. +pub mod invocation_request { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Payload { + #[prost(message, tag = "4")] + Value(::prost_types::Any), + #[prost(message, tag = "7")] + Noop(super::Noop), + } +} +/// ActorInvocation is a translation message between a local invocation made via InvocationRequest +/// and the real Actor that intends to respond to this invocation and that can be located anywhere in the cluster. +/// +/// Params: +/// * actor: The ActorId handling the InvocationRequest request, also called the target Actor. +/// * command_name: The function or method on the target Actor that will receive this request +/// and perform some useful computation with the sent data. +/// * current_context: The current Context with current state value of the target Actor. +/// That is, the same as found via matching in %Actor{name: target_actor, state: %ActorState{state: value} = actor_state}. +/// In this case, the Context type will contain in the value attribute the same `value` as the matching above. +/// * payload: The value to be passed to the function or method corresponding to command_name. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorInvocation { + #[prost(message, optional, tag = "1")] + pub actor: ::core::option::Option, + #[prost(string, tag = "2")] + pub command_name: ::prost::alloc::string::String, + #[prost(message, optional, tag = "3")] + pub current_context: ::core::option::Option, + #[prost(message, optional, tag = "6")] + pub caller: ::core::option::Option, + #[prost(oneof = "actor_invocation::Payload", tags = "4, 5")] + pub payload: ::core::option::Option, +} +/// Nested message and enum types in `ActorInvocation`. +pub mod actor_invocation { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Payload { + #[prost(message, tag = "4")] + Value(::prost_types::Any), + #[prost(message, tag = "5")] + Noop(super::Noop), + } +} +/// The user function's response after executing the action originated by the local proxy request via ActorInvocation. +/// +/// Params: +/// actor_name: The name of the Actor handling the InvocationRequest request, also called the target Actor. +/// actor_system: The name of ActorSystem registered in Registration step. +/// updated_context: The Context with updated state value of the target Actor after user function has processed a request. +/// value: The value that the original request proxy will forward in response to the InvocationRequest type request. +/// This is the final response from the point of view of the user who invoked the Actor call and its subsequent processing. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActorInvocationResponse { + #[prost(string, tag = "1")] + pub actor_name: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub actor_system: ::prost::alloc::string::String, + #[prost(message, optional, tag = "3")] + pub updated_context: ::core::option::Option, + #[prost(message, optional, tag = "5")] + pub workflow: ::core::option::Option, + #[prost(oneof = "actor_invocation_response::Payload", tags = "4, 6")] + pub payload: ::core::option::Option, +} +/// Nested message and enum types in `ActorInvocationResponse`. +pub mod actor_invocation_response { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Payload { + #[prost(message, tag = "4")] + Value(::prost_types::Any), + #[prost(message, tag = "6")] + Noop(super::Noop), + } +} +/// InvocationResponse is the response that the proxy that received the InvocationRequest request will forward to the request's original user function. +/// +/// Params: +/// status: Status of request. Could be one of [UNKNOWN, OK, ACTOR_NOT_FOUND, ERROR]. +/// system: The original ActorSystem of the InvocationRequest request. +/// actor: The target Actor originally sent in the InvocationRequest message. +/// value: The value resulting from the request processing that the target Actor made. +/// This value must be passed by the user function to the one who requested the initial request in InvocationRequest. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct InvocationResponse { + #[prost(message, optional, tag = "1")] + pub status: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub system: ::core::option::Option, + #[prost(message, optional, tag = "3")] + pub actor: ::core::option::Option, + #[prost(oneof = "invocation_response::Payload", tags = "4, 5")] + pub payload: ::core::option::Option, +} +/// Nested message and enum types in `InvocationResponse`. +pub mod invocation_response { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Payload { + #[prost(message, tag = "4")] + Value(::prost_types::Any), + #[prost(message, tag = "5")] + Noop(super::Noop), + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RequestStatus { + #[prost(enumeration = "Status", tag = "1")] + pub status: i32, + #[prost(string, tag = "2")] + pub message: ::prost::alloc::string::String, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum Status { + Unknown = 0, + Ok = 1, + ActorNotFound = 2, + Error = 3, +} +impl Status { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Status::Unknown => "UNKNOWN", + Status::Ok => "OK", + Status::ActorNotFound => "ACTOR_NOT_FOUND", + Status::Error => "ERROR", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UNKNOWN" => Some(Self::Unknown), + "OK" => Some(Self::Ok), + "ACTOR_NOT_FOUND" => Some(Self::ActorNotFound), + "ERROR" => Some(Self::Error), + _ => None, + } + } +} diff --git a/spawn-rs/src/eigr/spawn/eigr.functions.protocol.actors.rs b/spawn-rs/src/eigr/spawn/eigr.functions.protocol.actors.rs deleted file mode 100644 index 51a331b..0000000 --- a/spawn-rs/src/eigr/spawn/eigr.functions.protocol.actors.rs +++ /dev/null @@ -1,218 +0,0 @@ -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Registry { - #[prost(map = "string, message", tag = "1")] - pub actors: ::std::collections::HashMap<::prost::alloc::string::String, Actor>, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorSystem { - #[prost(string, tag = "1")] - pub name: ::prost::alloc::string::String, - #[prost(message, optional, tag = "2")] - pub registry: ::core::option::Option, -} -/// A strategy for save state. -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorSnapshotStrategy { - #[prost(oneof = "actor_snapshot_strategy::Strategy", tags = "1")] - pub strategy: ::core::option::Option, -} -/// Nested message and enum types in `ActorSnapshotStrategy`. -pub mod actor_snapshot_strategy { - #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Oneof)] - pub enum Strategy { - /// the timeout strategy. - #[prost(message, tag = "1")] - Timeout(super::TimeoutStrategy), - } -} -/// A strategy which a user function's entity is passivated. -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorDeactivationStrategy { - #[prost(oneof = "actor_deactivation_strategy::Strategy", tags = "1")] - pub strategy: ::core::option::Option, -} -/// Nested message and enum types in `ActorDeactivationStrategy`. -pub mod actor_deactivation_strategy { - #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Oneof)] - pub enum Strategy { - /// the timeout strategy. - #[prost(message, tag = "1")] - Timeout(super::TimeoutStrategy), - } -} -/// A strategy based on a timeout. -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct TimeoutStrategy { - /// The timeout in millis - #[prost(int64, tag = "1")] - pub timeout: i64, -} -/// A command represents an action that the user can perform on an Actor. -/// Commands in supporting languages are represented by functions or methods. -/// An Actor command has nothing to do with the semantics of Commands in a CQRS/EventSourced system. -/// It just represents an action that supporting languages can invoke. -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Command { - /// The name of the function or method in the supporting language that has been registered in Ator. - #[prost(string, tag = "1")] - pub name: ::prost::alloc::string::String, -} -/// A FixedTimerCommand is similar to a regular Command, its main differences are that it is scheduled to run at regular intervals -/// and only takes the actor's state as an argument. -/// Timer Commands are good for executing loops that manipulate the actor's own state. -/// In Elixir or other languages in BEAM it would be similar to invoking Process.send_after(self(), atom, msg, timeout) -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct FixedTimerCommand { - /// The time to wait until the command is triggered - #[prost(int32, tag = "1")] - pub seconds: i32, - /// See Command description Above - #[prost(message, optional, tag = "2")] - pub command: ::core::option::Option, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorState { - #[prost(map = "string, string", tag = "1")] - pub tags: ::std::collections::HashMap< - ::prost::alloc::string::String, - ::prost::alloc::string::String, - >, - #[prost(message, optional, tag = "2")] - pub state: ::core::option::Option<::prost_types::Any>, -} -/// TODO doc here -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Metadata { - /// A channel group represents a way to send commands to various actors - /// that belong to a certain semantic group. - #[prost(string, tag = "1")] - pub channel_group: ::prost::alloc::string::String, - #[prost(map = "string, string", tag = "2")] - pub tags: ::std::collections::HashMap< - ::prost::alloc::string::String, - ::prost::alloc::string::String, - >, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorSettings { - /// Indicates the type of Actor to be configured. - #[prost(enumeration = "Kind", tag = "1")] - pub kind: i32, - /// Indicates whether an actor's state should be persisted in a definitive store. - #[prost(bool, tag = "2")] - pub stateful: bool, - /// Snapshot strategy - #[prost(message, optional, tag = "3")] - pub snapshot_strategy: ::core::option::Option, - /// Deactivate strategy - #[prost(message, optional, tag = "4")] - pub deactivation_strategy: ::core::option::Option, - /// When kind is POOLED this is used to define minimun actor instances - #[prost(int32, tag = "5")] - pub min_pool_size: i32, - /// When kind is POOLED this is used to define maximum actor instances - #[prost(int32, tag = "6")] - pub max_pool_size: i32, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorId { - /// The name of a Actor Entity. - #[prost(string, tag = "1")] - pub name: ::prost::alloc::string::String, - /// Name of a ActorSystem - #[prost(string, tag = "2")] - pub system: ::prost::alloc::string::String, - /// When the Actor is of the Abstract type, - /// the name of the parent Actor must be informed here. - #[prost(string, tag = "3")] - pub parent: ::prost::alloc::string::String, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Actor { - /// Actor Identification - #[prost(message, optional, tag = "1")] - pub id: ::core::option::Option, - /// A Actor state. - #[prost(message, optional, tag = "2")] - pub state: ::core::option::Option, - /// Actor metadata - #[prost(message, optional, tag = "6")] - pub metadata: ::core::option::Option, - /// Actor settings. - #[prost(message, optional, tag = "3")] - pub settings: ::core::option::Option, - /// The commands registered for an actor - #[prost(message, repeated, tag = "4")] - pub commands: ::prost::alloc::vec::Vec, - /// The registered timer commands for an actor. - #[prost(message, repeated, tag = "5")] - pub timer_commands: ::prost::alloc::vec::Vec, -} -/// The type that defines the runtime characteristics of the Actor. -/// Regardless of the type of actor it is important that -/// all actors are registered during the proxy and host initialization phase. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] -#[repr(i32)] -pub enum Kind { - /// When no type is informed, the default to be assumed will be the Singleton pattern. - UnknowKind = 0, - /// Abstract actors are used to create children of this based actor at runtime - Abstract = 1, - /// Singleton actors as the name suggests have only one real instance of themselves running - /// during their entire lifecycle. That is, they are the opposite of the Abstract type Actors. - Singleton = 2, - /// Pooled Actors are similar to abstract actors, but unlike them, - /// their identifying name will always be the one registered at the system initialization stage. - /// The great advantage of Pooled actors is that they have multiple instances of themselves - /// acting as a request service pool. - /// Pooled actors are also stateless actors, that is, they will not have their - /// in-memory state persisted via Statesstore. This is done to avoid problems - /// with the correctness of the stored state. - /// Pooled Actors are generally used for tasks where the Actor Model would perform worse - /// than other concurrency models and for tasks that do not require state concerns. - /// Integration flows, data caching, proxies are good examples of use cases - /// for this type of Actor. - Pooled = 3, - /// Reserved for future use - Proxy = 4, -} -impl Kind { - /// String value of the enum field names used in the ProtoBuf definition. - /// - /// The values are not transformed in any way and thus are considered stable - /// (if the ProtoBuf definition does not change) and safe for programmatic use. - pub fn as_str_name(&self) -> &'static str { - match self { - Kind::UnknowKind => "UNKNOW_KIND", - Kind::Abstract => "ABSTRACT", - Kind::Singleton => "SINGLETON", - Kind::Pooled => "POOLED", - Kind::Proxy => "PROXY", - } - } - /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { - match value { - "UNKNOW_KIND" => Some(Self::UnknowKind), - "ABSTRACT" => Some(Self::Abstract), - "SINGLETON" => Some(Self::Singleton), - "POOLED" => Some(Self::Pooled), - "PROXY" => Some(Self::Proxy), - _ => None, - } - } -} diff --git a/spawn-rs/src/eigr/spawn/eigr.spawn.rs b/spawn-rs/src/eigr/spawn/eigr.spawn.rs deleted file mode 100644 index 38e5786..0000000 --- a/spawn-rs/src/eigr/spawn/eigr.spawn.rs +++ /dev/null @@ -1,278 +0,0 @@ -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Registry { - #[prost(map="string, message", tag="1")] - pub actors: ::std::collections::HashMap<::prost::alloc::string::String, Actor>, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorSystem { - #[prost(string, tag="1")] - pub name: ::prost::alloc::string::String, - #[prost(message, optional, tag="2")] - pub registry: ::core::option::Option, -} -/// A strategy for save state. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorSnapshotStrategy { - #[prost(oneof="actor_snapshot_strategy::Strategy", tags="1")] - pub strategy: ::core::option::Option, -} -/// Nested message and enum types in `ActorSnapshotStrategy`. -pub mod actor_snapshot_strategy { - #[derive(Clone, PartialEq, ::prost::Oneof)] - pub enum Strategy { - /// the timeout strategy. - #[prost(message, tag="1")] - Timeout(super::TimeoutStrategy), - } -} -/// A strategy which a user function's entity is passivated. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorDeactivateStrategy { - #[prost(oneof="actor_deactivate_strategy::Strategy", tags="1")] - pub strategy: ::core::option::Option, -} -/// Nested message and enum types in `ActorDeactivateStrategy`. -pub mod actor_deactivate_strategy { - #[derive(Clone, PartialEq, ::prost::Oneof)] - pub enum Strategy { - /// the timeout strategy. - #[prost(message, tag="1")] - Timeout(super::TimeoutStrategy), - } -} -/// A strategy based on a timeout. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct TimeoutStrategy { - /// The timeout in millis - #[prost(int64, tag="1")] - pub timeout: i64, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorState { - #[prost(map="string, string", tag="1")] - pub tags: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, - #[prost(message, optional, tag="2")] - pub state: ::core::option::Option<::prost_types::Any>, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorSettings { - /// Indicates if actor´s is abstract or non abstract. - #[prost(bool, tag="1")] - pub r#abstract: bool, - /// Indicates whether an actor's state should be persisted in a definitive store. - #[prost(bool, tag="2")] - pub persistent: bool, - /// Snapshot strategy - #[prost(message, optional, tag="3")] - pub snapshot_strategy: ::core::option::Option, - /// Deactivate strategy - #[prost(message, optional, tag="4")] - pub deactivate_strategy: ::core::option::Option, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorId { - /// The name of a Actor Entity. - #[prost(string, tag="1")] - pub name: ::prost::alloc::string::String, - /// Name of a ActorSystem - #[prost(string, tag="2")] - pub system: ::prost::alloc::string::String, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Actor { - /// Actor Identification - #[prost(message, optional, tag="1")] - pub id: ::core::option::Option, - /// A Actor state. - #[prost(message, optional, tag="2")] - pub state: ::core::option::Option, - /// Actor settings. - #[prost(message, optional, tag="3")] - pub settings: ::core::option::Option, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct SpawnRequest { - #[prost(message, optional, tag="2")] - pub actor_system: ::core::option::Option, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct SpawnResponse { - #[prost(message, optional, tag="1")] - pub status: ::core::option::Option, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct RegistrationRequest { - #[prost(message, optional, tag="1")] - pub service_info: ::core::option::Option, - #[prost(message, optional, tag="2")] - pub actor_system: ::core::option::Option, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ServiceInfo { - /// The name of the actor system, eg, "my-actor-system". - #[prost(string, tag="1")] - pub service_name: ::prost::alloc::string::String, - /// The version of the service. - #[prost(string, tag="2")] - pub service_version: ::prost::alloc::string::String, - /// A description of the runtime for the service. Can be anything, but examples might be: - /// - node v10.15.2 - /// - OpenJDK Runtime Environment 1.8.0_192-b12 - #[prost(string, tag="3")] - pub service_runtime: ::prost::alloc::string::String, - /// If using a support library, the name of that library, eg "spawn-jvm" - #[prost(string, tag="4")] - pub support_library_name: ::prost::alloc::string::String, - /// The version of the support library being used. - #[prost(string, tag="5")] - pub support_library_version: ::prost::alloc::string::String, - /// Spawn protocol major version accepted by the support library. - #[prost(int32, tag="6")] - pub protocol_major_version: i32, - /// Spawn protocol minor version accepted by the support library. - #[prost(int32, tag="7")] - pub protocol_minor_version: i32, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProxyInfo { - #[prost(int32, tag="1")] - pub protocol_major_version: i32, - #[prost(int32, tag="2")] - pub protocol_minor_version: i32, - #[prost(string, tag="3")] - pub proxy_name: ::prost::alloc::string::String, - #[prost(string, tag="4")] - pub proxy_version: ::prost::alloc::string::String, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct RegistrationResponse { - #[prost(message, optional, tag="1")] - pub status: ::core::option::Option, - #[prost(message, optional, tag="2")] - pub proxy_info: ::core::option::Option, -} -/// Context is where current and/or updated state is stored -/// to be transmitted to/from proxy and user function -/// -/// Params: -/// * state: Actor state passed back and forth between proxy and user function. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Context { - #[prost(message, optional, tag="1")] - pub state: ::core::option::Option<::prost_types::Any>, -} -/// The user function when it wants to send a message to an Actor uses the InvocationRequest message type. -/// -/// Params: -/// * system: See ActorStstem message. -/// * actor: The target Actor, i.e. the one that the user function is calling to perform some computation. -/// * command_name: The function or method on the target Actor that will receive this request -/// and perform some useful computation with the sent data. -/// * value: This is the value sent by the user function to be computed by the request's target Actor command. -/// * async: Indicates whether the command should be processed synchronously, where a response should be sent back to the user function, -/// or whether the command should be processed asynchronously, i.e. no response sent to the caller and no waiting. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct InvocationRequest { - #[prost(message, optional, tag="1")] - pub system: ::core::option::Option, - #[prost(message, optional, tag="2")] - pub actor: ::core::option::Option, - #[prost(string, tag="3")] - pub command_name: ::prost::alloc::string::String, - #[prost(message, optional, tag="4")] - pub value: ::core::option::Option<::prost_types::Any>, - #[prost(bool, tag="5")] - pub r#async: bool, -} -/// ActorInvocation is a translation message between a local invocation made via InvocationRequest -/// and the real Actor that intends to respond to this invocation and that can be located anywhere in the cluster. -/// -/// Params: -/// actor_name: The name of the Actor handling the InvocationRequest request, also called the target Actor. -/// actor_system: The name of ActorSystem registered in Registration step. -/// command_name: The function or method on the target Actor that will receive this request -/// and perform some useful computation with the sent data. -/// current_context: The current Context with current state value of the target Actor. -/// That is, the same as found via matching in %Actor{name: target_actor, state: %ActorState{state: value} = actor_state}. -/// In this case, the Context type will contain in the value attribute the same `value` as the matching above. -/// value: The value to be passed to the function or method corresponding to command_name. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorInvocation { - #[prost(string, tag="1")] - pub actor_name: ::prost::alloc::string::String, - #[prost(string, tag="2")] - pub actor_system: ::prost::alloc::string::String, - #[prost(string, tag="3")] - pub command_name: ::prost::alloc::string::String, - #[prost(message, optional, tag="4")] - pub current_context: ::core::option::Option, - #[prost(message, optional, tag="5")] - pub value: ::core::option::Option<::prost_types::Any>, -} -/// The user function's response after executing the action originated by the local proxy request via ActorInvocation. -/// -/// Params: -/// actor_name: The name of the Actor handling the InvocationRequest request, also called the target Actor. -/// actor_system: The name of ActorSystem registered in Registration step. -/// updated_context: The Context with updated state value of the target Actor after user function has processed a request. -/// value: The value that the original request proxy will forward in response to the InvocationRequest type request. -/// This is the final response from the point of view of the user who invoked the Actor call and its subsequent processing. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ActorInvocationResponse { - #[prost(string, tag="1")] - pub actor_name: ::prost::alloc::string::String, - #[prost(string, tag="2")] - pub actor_system: ::prost::alloc::string::String, - #[prost(message, optional, tag="3")] - pub updated_context: ::core::option::Option, - #[prost(message, optional, tag="4")] - pub value: ::core::option::Option<::prost_types::Any>, -} -/// InvocationResponse is the response that the proxy that received the InvocationRequest request will forward to the request's original user function. -/// -/// Params: -/// status: Status of request. Could be one of [UNKNOWN, OK, ACTOR_NOT_FOUND, ERROR]. -/// sytem: The original ActorSystem of the InvocationRequest request. -/// actor: The target Actor originally sent in the InvocationRequest message. -/// value: The value resulting from the request processing that the target Actor made. -/// This value must be passed by the user function to the one who requested the initial request in InvocationRequest. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct InvocationResponse { - #[prost(message, optional, tag="1")] - pub status: ::core::option::Option, - #[prost(message, optional, tag="2")] - pub system: ::core::option::Option, - #[prost(message, optional, tag="3")] - pub actor: ::core::option::Option, - #[prost(message, optional, tag="4")] - pub value: ::core::option::Option<::prost_types::Any>, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct RequestStatus { - #[prost(enumeration="Status", tag="1")] - pub status: i32, - #[prost(string, tag="2")] - pub message: ::prost::alloc::string::String, -} -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] -#[repr(i32)] -pub enum Status { - Unknown = 0, - Ok = 1, - ActorNotFound = 2, - Error = 3, -} -impl Status { - /// String value of the enum field names used in the ProtoBuf definition. - /// - /// The values are not transformed in any way and thus are considered stable - /// (if the ProtoBuf definition does not change) and safe for programmatic use. - pub fn as_str_name(&self) -> &'static str { - match self { - Status::Unknown => "UNKNOWN", - Status::Ok => "OK", - Status::ActorNotFound => "ACTOR_NOT_FOUND", - Status::Error => "ERROR", - } - } -} diff --git a/spawn-rs/src/handler/callback.rs b/spawn-rs/src/handler/callback.rs index 0de2c9d..885bd90 100644 --- a/spawn-rs/src/handler/callback.rs +++ b/spawn-rs/src/handler/callback.rs @@ -1,10 +1,19 @@ pub mod v1 { + use std::cell::Cell; + use crate::actor::Actor; + use crate::eigr::spawn::ActorInvocation; - use actix_web::{post, web::Data, HttpRequest, Responder}; + use actix_protobuf::ProtoBuf; + use actix_web::{http::header::ContentType, post, web::Data, HttpResponse, Responder}; #[post("/actions")] - pub async fn handle(_data: Data>>, _req: HttpRequest) -> impl Responder { - "Hello World from v1 API!" + pub async fn handle( + ctx: Data>>>, + req: ProtoBuf, + ) -> impl Responder { + HttpResponse::Ok() + .content_type(ContentType::plaintext()) + .body(format!("Hello !")) } } diff --git a/spawn-rs/src/lib.rs b/spawn-rs/src/lib.rs index efa5653..1a1fd05 100644 --- a/spawn-rs/src/lib.rs +++ b/spawn-rs/src/lib.rs @@ -1,17 +1,43 @@ extern crate actix_web; extern crate prost_types; -mod eigr { - #[path = "eigr.functions.protocol.actors.rs"] - pub mod actors {} - - #[path = "eigr.functions.protocol.rs"] - pub mod protocol {} -} +mod eigr; pub mod action; pub mod actor; pub mod context; pub mod handler; +pub mod serializer; pub mod spawn; pub mod value; + +use prost_types::Any; + +#[derive(Debug, Clone)] +pub struct Message { + action: String, + body: Any, +} + +impl Default for Message { + fn default() -> Message { + Message { + action: String::from(""), + body: Any::default(), + } + } +} + +impl Message { + pub fn new() -> Self { + Default::default() + } + + pub fn action(&self) -> &str { + &self.action + } + + pub fn body(&self) -> &Any { + &self.body + } +} diff --git a/spawn-rs/src/serializer.rs b/spawn-rs/src/serializer.rs new file mode 100644 index 0000000..a664f20 --- /dev/null +++ b/spawn-rs/src/serializer.rs @@ -0,0 +1,12 @@ +use crate::actor::Actor; + +#[allow(unused_variables)] +pub trait Serializer +where + Self: Actor, +{ + /// This method is called for every message received by this actor. + fn decode(&mut self, msg: prost_types::Any) -> Box; + + fn encode(&mut self, msg: Box) -> prost_types::Any; +} diff --git a/spawn-rs/src/spawn.rs b/spawn-rs/src/spawn.rs index 5dee2c6..d071ef0 100644 --- a/spawn-rs/src/spawn.rs +++ b/spawn-rs/src/spawn.rs @@ -1,11 +1,11 @@ use crate::actor::Actor; use crate::handler::callback; -use std::io::Result; +use std::{cell::Cell, io::Result}; use actix_web::{ middleware, - web::{self}, + web::{self, Data}, App, HttpServer, }; @@ -59,8 +59,12 @@ impl Spawn { pub async fn start(&mut self) -> Result<()> { let server = HttpServer::new(move || { + //let actors: Vec<&Box> = self.get_actors(); + + //let actors_cell: Cell>> = Cell::new(self.get_actors()); + App::new() - //.app_data(self.get_actors()) + .app_data(Data::new("")) .wrap(middleware::Logger::default()) .configure(Self::config) })