refactor: introduce TransportActor abstraction
This commit is contained in:
178
app/.dart_tool/package_config.json
Normal file
178
app/.dart_tool/package_config.json
Normal file
@@ -0,0 +1,178 @@
|
||||
{
|
||||
"configVersion": 2,
|
||||
"packages": [
|
||||
{
|
||||
"name": "async",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/async-2.13.0",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.4"
|
||||
},
|
||||
{
|
||||
"name": "boolean_selector",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/boolean_selector-2.1.2",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.1"
|
||||
},
|
||||
{
|
||||
"name": "characters",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/characters-1.4.0",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.4"
|
||||
},
|
||||
{
|
||||
"name": "clock",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/clock-1.1.2",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.4"
|
||||
},
|
||||
{
|
||||
"name": "collection",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/collection-1.19.1",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.4"
|
||||
},
|
||||
{
|
||||
"name": "cupertino_icons",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.8",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.1"
|
||||
},
|
||||
{
|
||||
"name": "fake_async",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/fake_async-1.3.3",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.3"
|
||||
},
|
||||
{
|
||||
"name": "flutter",
|
||||
"rootUri": "file:///Users/kaska/.local/share/mise/installs/flutter/3.38.9-stable/packages/flutter",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.8"
|
||||
},
|
||||
{
|
||||
"name": "flutter_lints",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/flutter_lints-6.0.0",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.8"
|
||||
},
|
||||
{
|
||||
"name": "flutter_test",
|
||||
"rootUri": "file:///Users/kaska/.local/share/mise/installs/flutter/3.38.9-stable/packages/flutter_test",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.8"
|
||||
},
|
||||
{
|
||||
"name": "leak_tracker",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/leak_tracker-11.0.2",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.2"
|
||||
},
|
||||
{
|
||||
"name": "leak_tracker_flutter_testing",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/leak_tracker_flutter_testing-3.0.10",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.2"
|
||||
},
|
||||
{
|
||||
"name": "leak_tracker_testing",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/leak_tracker_testing-3.0.2",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.2"
|
||||
},
|
||||
{
|
||||
"name": "lints",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/lints-6.1.0",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.8"
|
||||
},
|
||||
{
|
||||
"name": "matcher",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/matcher-0.12.17",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.4"
|
||||
},
|
||||
{
|
||||
"name": "material_color_utilities",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/material_color_utilities-0.11.1",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "2.17"
|
||||
},
|
||||
{
|
||||
"name": "meta",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/meta-1.17.0",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.5"
|
||||
},
|
||||
{
|
||||
"name": "path",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/path-1.9.1",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.4"
|
||||
},
|
||||
{
|
||||
"name": "sky_engine",
|
||||
"rootUri": "file:///Users/kaska/.local/share/mise/installs/flutter/3.38.9-stable/bin/cache/pkg/sky_engine",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.8"
|
||||
},
|
||||
{
|
||||
"name": "source_span",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/source_span-1.10.2",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.1"
|
||||
},
|
||||
{
|
||||
"name": "stack_trace",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/stack_trace-1.12.1",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.4"
|
||||
},
|
||||
{
|
||||
"name": "stream_channel",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/stream_channel-2.1.4",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.3"
|
||||
},
|
||||
{
|
||||
"name": "string_scanner",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/string_scanner-1.4.1",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.1"
|
||||
},
|
||||
{
|
||||
"name": "term_glyph",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/term_glyph-1.2.2",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.1"
|
||||
},
|
||||
{
|
||||
"name": "test_api",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/test_api-0.7.7",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.5"
|
||||
},
|
||||
{
|
||||
"name": "vector_math",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/vector_math-2.2.0",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.1"
|
||||
},
|
||||
{
|
||||
"name": "vm_service",
|
||||
"rootUri": "file:///Users/kaska/.pub-cache/hosted/pub.dev/vm_service-15.0.2",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.5"
|
||||
},
|
||||
{
|
||||
"name": "app",
|
||||
"rootUri": "../",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "3.10"
|
||||
}
|
||||
],
|
||||
"generator": "pub",
|
||||
"generatorVersion": "3.10.8",
|
||||
"flutterRoot": "file:///Users/kaska/.local/share/mise/installs/flutter/3.38.9-stable",
|
||||
"flutterVersion": "3.38.9",
|
||||
"pubCache": "file:///Users/kaska/.pub-cache"
|
||||
}
|
||||
230
app/.dart_tool/package_graph.json
Normal file
230
app/.dart_tool/package_graph.json
Normal file
@@ -0,0 +1,230 @@
|
||||
{
|
||||
"roots": [
|
||||
"app"
|
||||
],
|
||||
"packages": [
|
||||
{
|
||||
"name": "app",
|
||||
"version": "1.0.0+1",
|
||||
"dependencies": [
|
||||
"cupertino_icons",
|
||||
"flutter"
|
||||
],
|
||||
"devDependencies": [
|
||||
"flutter_lints",
|
||||
"flutter_test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "flutter_lints",
|
||||
"version": "6.0.0",
|
||||
"dependencies": [
|
||||
"lints"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "flutter_test",
|
||||
"version": "0.0.0",
|
||||
"dependencies": [
|
||||
"clock",
|
||||
"collection",
|
||||
"fake_async",
|
||||
"flutter",
|
||||
"leak_tracker_flutter_testing",
|
||||
"matcher",
|
||||
"meta",
|
||||
"path",
|
||||
"stack_trace",
|
||||
"stream_channel",
|
||||
"test_api",
|
||||
"vector_math"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cupertino_icons",
|
||||
"version": "1.0.8",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "flutter",
|
||||
"version": "0.0.0",
|
||||
"dependencies": [
|
||||
"characters",
|
||||
"collection",
|
||||
"material_color_utilities",
|
||||
"meta",
|
||||
"sky_engine",
|
||||
"vector_math"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "lints",
|
||||
"version": "6.1.0",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "stream_channel",
|
||||
"version": "2.1.4",
|
||||
"dependencies": [
|
||||
"async"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "meta",
|
||||
"version": "1.17.0",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "collection",
|
||||
"version": "1.19.1",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "leak_tracker_flutter_testing",
|
||||
"version": "3.0.10",
|
||||
"dependencies": [
|
||||
"flutter",
|
||||
"leak_tracker",
|
||||
"leak_tracker_testing",
|
||||
"matcher",
|
||||
"meta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "vector_math",
|
||||
"version": "2.2.0",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "stack_trace",
|
||||
"version": "1.12.1",
|
||||
"dependencies": [
|
||||
"path"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "clock",
|
||||
"version": "1.1.2",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "fake_async",
|
||||
"version": "1.3.3",
|
||||
"dependencies": [
|
||||
"clock",
|
||||
"collection"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "path",
|
||||
"version": "1.9.1",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "matcher",
|
||||
"version": "0.12.17",
|
||||
"dependencies": [
|
||||
"async",
|
||||
"meta",
|
||||
"stack_trace",
|
||||
"term_glyph",
|
||||
"test_api"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "test_api",
|
||||
"version": "0.7.7",
|
||||
"dependencies": [
|
||||
"async",
|
||||
"boolean_selector",
|
||||
"collection",
|
||||
"meta",
|
||||
"source_span",
|
||||
"stack_trace",
|
||||
"stream_channel",
|
||||
"string_scanner",
|
||||
"term_glyph"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "sky_engine",
|
||||
"version": "0.0.0",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "material_color_utilities",
|
||||
"version": "0.11.1",
|
||||
"dependencies": [
|
||||
"collection"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "characters",
|
||||
"version": "1.4.0",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "async",
|
||||
"version": "2.13.0",
|
||||
"dependencies": [
|
||||
"collection",
|
||||
"meta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leak_tracker_testing",
|
||||
"version": "3.0.2",
|
||||
"dependencies": [
|
||||
"leak_tracker",
|
||||
"matcher",
|
||||
"meta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "leak_tracker",
|
||||
"version": "11.0.2",
|
||||
"dependencies": [
|
||||
"clock",
|
||||
"collection",
|
||||
"meta",
|
||||
"path",
|
||||
"vm_service"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "term_glyph",
|
||||
"version": "1.2.2",
|
||||
"dependencies": []
|
||||
},
|
||||
{
|
||||
"name": "string_scanner",
|
||||
"version": "1.4.1",
|
||||
"dependencies": [
|
||||
"source_span"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "source_span",
|
||||
"version": "1.10.2",
|
||||
"dependencies": [
|
||||
"collection",
|
||||
"path",
|
||||
"term_glyph"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "boolean_selector",
|
||||
"version": "2.1.2",
|
||||
"dependencies": [
|
||||
"source_span",
|
||||
"string_scanner"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "vm_service",
|
||||
"version": "15.0.2",
|
||||
"dependencies": []
|
||||
}
|
||||
],
|
||||
"configVersion": 1
|
||||
}
|
||||
1
app/.dart_tool/version
Normal file
1
app/.dart_tool/version
Normal file
@@ -0,0 +1 @@
|
||||
3.38.9
|
||||
11
app/macos/Flutter/ephemeral/Flutter-Generated.xcconfig
Normal file
11
app/macos/Flutter/ephemeral/Flutter-Generated.xcconfig
Normal file
@@ -0,0 +1,11 @@
|
||||
// This is a generated file; do not edit or check into version control.
|
||||
FLUTTER_ROOT=/Users/kaska/.local/share/mise/installs/flutter/3.38.9-stable
|
||||
FLUTTER_APPLICATION_PATH=/Users/kaska/Documents/Projects/Major/arbiter/app
|
||||
COCOAPODS_PARALLEL_CODE_SIGN=true
|
||||
FLUTTER_BUILD_DIR=build
|
||||
FLUTTER_BUILD_NAME=1.0.0
|
||||
FLUTTER_BUILD_NUMBER=1
|
||||
DART_OBFUSCATION=false
|
||||
TRACK_WIDGET_CREATION=true
|
||||
TREE_SHAKE_ICONS=false
|
||||
PACKAGE_CONFIG=.dart_tool/package_config.json
|
||||
12
app/macos/Flutter/ephemeral/flutter_export_environment.sh
Executable file
12
app/macos/Flutter/ephemeral/flutter_export_environment.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
# This is a generated file; do not edit or check into version control.
|
||||
export "FLUTTER_ROOT=/Users/kaska/.local/share/mise/installs/flutter/3.38.9-stable"
|
||||
export "FLUTTER_APPLICATION_PATH=/Users/kaska/Documents/Projects/Major/arbiter/app"
|
||||
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
|
||||
export "FLUTTER_BUILD_DIR=build"
|
||||
export "FLUTTER_BUILD_NAME=1.0.0"
|
||||
export "FLUTTER_BUILD_NUMBER=1"
|
||||
export "DART_OBFUSCATION=false"
|
||||
export "TRACK_WIDGET_CREATION=true"
|
||||
export "TREE_SHAKE_ICONS=false"
|
||||
export "PACKAGE_CONFIG=.dart_tool/package_config.json"
|
||||
1
server/Cargo.lock
generated
1
server/Cargo.lock
generated
@@ -73,6 +73,7 @@ dependencies = [
|
||||
"tonic",
|
||||
"tonic-prost",
|
||||
"tonic-prost-build",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ miette.workspace = true
|
||||
thiserror.workspace = true
|
||||
rustls-pki-types.workspace = true
|
||||
base64 = "0.22.1"
|
||||
tracing.workspace = true
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
use futures::{Stream, StreamExt};
|
||||
use tokio::sync::mpsc::{self, error::SendError};
|
||||
use kameo::{
|
||||
Actor,
|
||||
actor::{ActorRef, PreparedActor, Spawn, WeakActorRef},
|
||||
mailbox::Signal,
|
||||
prelude::Message,
|
||||
};
|
||||
use tokio::{
|
||||
select,
|
||||
sync::mpsc::{self, error::SendError},
|
||||
};
|
||||
use tonic::{Status, Streaming};
|
||||
|
||||
use tracing::{debug, error};
|
||||
|
||||
// Abstraction for stream for sans-io capabilities
|
||||
pub trait Bi<T, U>: Stream<Item = Result<T, Status>> + Send + Sync + 'static {
|
||||
@@ -44,3 +53,136 @@ where
|
||||
self.response_sender.send(item).await
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TransportActor<T: Send + 'static>: Actor + Send + Message<T> {}
|
||||
|
||||
pub struct GrpcTransportActor<SendMsg, RecvMsg, A>
|
||||
where
|
||||
SendMsg: Send + 'static,
|
||||
RecvMsg: Send + 'static,
|
||||
A: TransportActor<RecvMsg>,
|
||||
{
|
||||
pub sender: mpsc::Sender<Result<SendMsg, tonic::Status>>,
|
||||
pub receiver: tonic::Streaming<RecvMsg>,
|
||||
pub business_logic_actor: ActorRef<A>,
|
||||
}
|
||||
impl<SendMsg, RecvMsg, A> Actor for GrpcTransportActor<SendMsg, RecvMsg, A>
|
||||
where
|
||||
SendMsg: Send + 'static,
|
||||
RecvMsg: Send + 'static,
|
||||
A: TransportActor<RecvMsg>,
|
||||
{
|
||||
type Args = Self;
|
||||
|
||||
type Error = ();
|
||||
|
||||
async fn on_start(args: Self::Args, _: ActorRef<Self>) -> Result<Self, Self::Error> {
|
||||
Ok(args)
|
||||
}
|
||||
|
||||
fn on_link_died(
|
||||
&mut self,
|
||||
_: WeakActorRef<Self>,
|
||||
id: kameo::prelude::ActorId,
|
||||
_: kameo::prelude::ActorStopReason,
|
||||
) -> impl Future<
|
||||
Output = Result<std::ops::ControlFlow<kameo::prelude::ActorStopReason>, Self::Error>,
|
||||
> + Send {
|
||||
async move {
|
||||
if id == self.business_logic_actor.id() {
|
||||
error!("Business logic actor died, stopping GrpcTransportActor");
|
||||
Ok(std::ops::ControlFlow::Break(
|
||||
kameo::prelude::ActorStopReason::Normal,
|
||||
))
|
||||
} else {
|
||||
debug!(
|
||||
"Linked actor {} died, but it's not the business logic actor, ignoring",
|
||||
id
|
||||
);
|
||||
Ok(std::ops::ControlFlow::Continue(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn next(
|
||||
&mut self,
|
||||
_: WeakActorRef<Self>,
|
||||
mailbox_rx: &mut kameo::prelude::MailboxReceiver<Self>,
|
||||
) -> Option<kameo::mailbox::Signal<Self>> {
|
||||
select! {
|
||||
msg = mailbox_rx.recv() => {
|
||||
msg
|
||||
}
|
||||
recv_msg = self.receiver.next() => {
|
||||
match recv_msg {
|
||||
Some(Ok(msg)) => {
|
||||
match self.business_logic_actor.tell(msg).await {
|
||||
Ok(_) => None,
|
||||
Err(e) => {
|
||||
// TODO: this would probably require better error handling - or resending if backpressure is the issue
|
||||
error!("Failed to send message to business logic actor: {}", e);
|
||||
Some(Signal::Stop)
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Err(e)) => {
|
||||
error!("Received error from stream: {}, stopping GrpcTransportActor", e);
|
||||
Some(Signal::Stop)
|
||||
}
|
||||
None => {
|
||||
error!("Receiver channel closed, stopping GrpcTransportActor");
|
||||
Some(Signal::Stop)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<SendMsg: Send + 'static, RecvMsg: Send + 'static, A: TransportActor<RecvMsg>> Message<SendMsg>
|
||||
for GrpcTransportActor<SendMsg, RecvMsg, A>
|
||||
{
|
||||
type Reply = ();
|
||||
|
||||
async fn handle(
|
||||
&mut self,
|
||||
msg: SendMsg,
|
||||
ctx: &mut kameo::prelude::Context<Self, Self::Reply>,
|
||||
) -> Self::Reply {
|
||||
let err = self.sender.send(Ok(msg)).await;
|
||||
match err {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
error!("Failed to send message: {}", e);
|
||||
ctx.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn wire<T, RecvMsg, SendMsg, BusinessActor, BusinessCtor, TransportCtor>(
|
||||
business_ctor: BusinessCtor,
|
||||
transport_ctor: TransportCtor,
|
||||
) -> (ActorRef<T>, ActorRef<BusinessActor>)
|
||||
where
|
||||
T: TransportActor<RecvMsg>,
|
||||
RecvMsg: Send + 'static,
|
||||
SendMsg: Send + 'static,
|
||||
BusinessActor: Actor + Send + 'static,
|
||||
BusinessCtor: FnOnce(ActorRef<T>) -> BusinessActor::Args,
|
||||
TransportCtor: FnOnce(ActorRef<BusinessActor>) -> T::Args,
|
||||
{
|
||||
let prepared_business: PreparedActor<BusinessActor> = Spawn::prepare();
|
||||
let prepared_transport: PreparedActor<T> = Spawn::prepare();
|
||||
|
||||
let business_ref = prepared_business.actor_ref().clone();
|
||||
let transport_ref = prepared_transport.actor_ref().clone();
|
||||
|
||||
transport_ref.link(&business_ref).await;
|
||||
business_ref.link(&transport_ref).await;
|
||||
|
||||
let _ = prepared_business.spawn(business_ctor(transport_ref.clone()));
|
||||
let _ = prepared_transport.spawn(transport_ctor(business_ref.clone()));
|
||||
|
||||
(transport_ref, business_ref)
|
||||
}
|
||||
|
||||
@@ -1,13 +1,67 @@
|
||||
use arbiter_proto::proto::UserAgentRequest;
|
||||
use ed25519_dalek::SigningKey;
|
||||
use kameo::Actor;
|
||||
use kameo::{
|
||||
Actor, Reply,
|
||||
actor::{ActorRef, WeakActorRef},
|
||||
prelude::Message,
|
||||
};
|
||||
use smlang::statemachine;
|
||||
use tokio::sync::mpsc;
|
||||
use tonic::transport::CertificateDer;
|
||||
use tracing::{debug, error};
|
||||
|
||||
struct Storage {
|
||||
pub identity: SigningKey,
|
||||
pub server_ca_cert: CertificateDer<'static>,
|
||||
}
|
||||
|
||||
#[derive(Actor)]
|
||||
pub struct UserAgent {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum InitError {
|
||||
StorageError,
|
||||
Other(String),
|
||||
}
|
||||
|
||||
statemachine! {
|
||||
name: UserAgentStateMachine,
|
||||
custom_error: false,
|
||||
transitions: {
|
||||
*Init + SendAuthChallenge = WaitingForAuthSolution
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub struct UserAgentActor<A: TransportActor<UserAgentRequest>> {
|
||||
key: SigningKey,
|
||||
server_ca_cert: CertificateDer<'static>,
|
||||
sender: ActorRef<A>,
|
||||
}
|
||||
impl<A: TransportActor<UserAgentRequest>> Actor for UserAgentActor<A> {
|
||||
type Args = Self;
|
||||
|
||||
type Error = InitError;
|
||||
|
||||
async fn on_start(args: Self::Args, actor_ref: ActorRef<Self>) -> Result<Self, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn on_link_died(
|
||||
&mut self,
|
||||
_: WeakActorRef<Self>,
|
||||
id: kameo::prelude::ActorId,
|
||||
_: kameo::prelude::ActorStopReason,
|
||||
) -> Result<std::ops::ControlFlow<kameo::prelude::ActorStopReason>, Self::Error> {
|
||||
if id == self.sender.id() {
|
||||
error!("Transport actor died, stopping UserAgentActor");
|
||||
Ok(std::ops::ControlFlow::Break(
|
||||
kameo::prelude::ActorStopReason::Normal,
|
||||
))
|
||||
} else {
|
||||
debug!(
|
||||
"Linked actor {} died, but it's not the transport actor, ignoring",
|
||||
id
|
||||
);
|
||||
Ok(std::ops::ControlFlow::Continue(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user