acton_core/traits/
actor.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
 * Copyright (c) 2024. Govcraft
 *
 * Licensed under either of
 *   * Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *   * MIT license: http://opensource.org/licenses/MIT
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the applicable License for the specific language governing permissions and
 * limitations under that License.
 */

use std::future::Future;

use acton_ern::{Ern};
use async_trait::async_trait;
use dashmap::DashMap;
use tokio_util::task::TaskTracker;
use tracing::*;

use crate::common::*;
use crate::message::{BrokerRequest, MessageAddress};
use crate::traits::acton_message::ActonMessage;

/// Trait for actor context, defining common methods for actor management.
#[async_trait]
pub trait Actor {
    /// Returns the message address for this agent.
    fn reply_address(&self) -> MessageAddress;
    /// Returns an envelope for the specified recipient and message, ready to send.
    fn create_envelope(&self, recipient_address: Option<MessageAddress>) -> OutboundEnvelope;
    /// Returns a map of the actor's children.
    fn children(&self) -> DashMap<String, AgentHandle>;

    /// Finds a child actor by its ERN.
    ///
    /// # Arguments
    ///
    /// * `arn` - The ERN of the child actor to find.
    ///
    /// # Returns
    ///
    /// An `Option<ActorRef>` containing the child actor if found, or `None` if not found.
    fn find_child(&self, arn: &Ern) -> Option<AgentHandle>;

    /// Returns the actor's task tracker.
    fn tracker(&self) -> TaskTracker;

    /// Returns the actor's ERN.
    fn id(&self) -> Ern;

    /// Returns the actor's root from the ERN.
    fn name(&self) -> String;

    /// Creates a clone of the actor's reference.
    fn clone_ref(&self) -> AgentHandle;

    /// Emits a message from the actor, possibly to a pool item.
    ///
    /// # Arguments
    ///
    /// * `message` - The message to emit, implementing `ActonMessage`.
    ///
    /// # Returns
    ///
    /// A `Future` that resolves when the message has been emitted.
    #[instrument(skip(self), fields(children = self.children().len()))]
    fn send(
        &self,
        message: impl ActonMessage,
    ) -> impl Future<Output=()> + Send + Sync + '_
    where
        Self: Sync,
    {
        async move {
            let envelope = self.create_envelope(None);
            trace!("Envelope sender is {:?}", envelope.return_address.sender.root.to_string());
            envelope.send(message).await;
        }
    }
    /// Send a message synchronously.
    fn send_sync(&self, message: impl ActonMessage, recipient: &AgentHandle) -> anyhow::Result<()>
    where
        Self: Actor,
    {
        let envelope = self.create_envelope(Some(recipient.reply_address()));
        envelope.reply(BrokerRequest::new(message))?;
        Ok(())
    }

    /// Suspends the actor.
    fn stop(&self) -> impl Future<Output=anyhow::Result<()>> + Send + Sync + '_;
}