Branch data Line data Source code
1 : : // Copyright 2026 HPActor Contributors
2 : : //
3 : : // Licensed under the Apache License, Version 2.0 (the "License");
4 : : // you may not use this file except in compliance with the License.
5 : : // You may obtain a copy of the License at
6 : : //
7 : : // http://www.apache.org/licenses/LICENSE-2.0
8 : : //
9 : : // Unless required by applicable law or agreed to in writing, software
10 : : // distributed under the License is distributed on an "AS IS" BASIS,
11 : : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : : // See the License for the specific language governing permissions and
13 : : // limitations under the License.
14 : :
15 : : #include <hpactor/actor/abstract_actor.hpp>
16 : : #include <hpactor/actor/lifecycle_actor.hpp>
17 : : #include <hpactor/actor_context.hpp>
18 : : #include <hpactor/messages.pb.h>
19 : :
20 : : #include <iostream>
21 : :
22 : : namespace hpactor {
23 : :
24 : 125 : AbstractActor::AbstractActor(ActorId id, ActorType type, ActorSystem& sys)
25 : 125 : : id_(id), type_(type), system_(sys) {}
26 : :
27 : 6 : void AbstractActor::link_to(const ActorAddr& other) {
28 : 6 : auto* ctx = actor_context();
29 : 6 : if (ctx == nullptr) {
30 : 2 : return;
31 : : }
32 : :
33 : : // Reject link-to-self
34 : 6 : if (other == address()) {
35 : 1 : std::cerr << "HPActor: link_to self (" << id().value() << ") ignored"
36 : 1 : << '\n';
37 : 1 : return;
38 : : }
39 : :
40 : : // Idempotency: check if already linked
41 : 5 : for (const auto& linked : ctx->linked_actors()) {
42 : 1 : if (linked == other) {
43 : 1 : return;
44 : : }
45 : 5 : }
46 : :
47 : 4 : ctx->add_linked(other);
48 : :
49 : : // Notify target via LinkMessage
50 : 4 : hpactor::LinkMessage pb;
51 : 4 : pb.set_actor_id(id().value());
52 : :
53 : 4 : StreamBuffer payload(pb.ByteSizeLong());
54 : 4 : (void)pb.SerializeToArray(payload.data(), static_cast<int>(payload.size()));
55 : :
56 : 4 : ctx->send(other, TypedMessage(TypeTag::LinkMsg, std::move(payload)));
57 : 4 : }
58 : :
59 : 1 : void AbstractActor::unlink_from(const ActorAddr& other) {
60 : 1 : auto* ctx = actor_context();
61 : 1 : if (ctx == nullptr) {
62 : 0 : return;
63 : : }
64 : :
65 : 1 : ctx->remove_linked(other);
66 : :
67 : : // Notify target via UnlinkMessage
68 : 1 : hpactor::UnlinkMessage pb;
69 : 1 : pb.set_actor_id(id().value());
70 : :
71 : 1 : StreamBuffer payload(pb.ByteSizeLong());
72 : 1 : (void)pb.SerializeToArray(payload.data(), static_cast<int>(payload.size()));
73 : :
74 : 1 : ctx->send(other, TypedMessage(TypeTag::UnlinkMsg, std::move(payload)));
75 : 1 : }
76 : :
77 : 2 : void AbstractActor::monitor(const ActorAddr& target) {
78 : 2 : auto* ctx = actor_context();
79 : 2 : if (ctx == nullptr) {
80 : 0 : return;
81 : : }
82 : :
83 : : // Send MonitorMsg to target. The target's receive() will add us
84 : : // to its monitored_ list so that on_exit() notifies us on death.
85 : 2 : ctx->send(target, TypedMessage(TypeTag::MonitorMsg, StreamBuffer{}));
86 : : }
87 : :
88 : 1 : void AbstractActor::demonitor(const ActorAddr& target) {
89 : 1 : auto* ctx = actor_context();
90 : 1 : if (ctx == nullptr) {
91 : 0 : return;
92 : : }
93 : :
94 : : // Send DemonitorMsg to target. The target's receive() will remove us
95 : : // from its monitored_ list.
96 : 1 : ctx->send(target, TypedMessage(TypeTag::DemonitorMsg, StreamBuffer{}));
97 : : }
98 : :
99 : 2 : cli::ActorMeta AbstractActor::to_metadata() const {
100 : 2 : cli::ActorMeta m;
101 : 2 : m.actor_id = id().value();
102 : 2 : m.actor_type = std::string(type_name());
103 : 2 : if (auto* lc = as_lifecycle()) {
104 : 1 : m.state = lc->state_string();
105 : 1 : m.incarnation = lc->incarnation();
106 : : } else {
107 : 1 : m.state = "unknown";
108 : 1 : m.incarnation = address().incarnation;
109 : : }
110 : 2 : return m;
111 : : }
112 : :
113 : 0 : void AbstractActor::set_scheduler(sched::IScheduler* /*scheduler*/) {
114 : : // Default no-op; EventBasedActor overrides this
115 : 0 : }
116 : :
117 : 0 : void AbstractActor::set_mailbox(mailbox::MPSCActorMailbox<TypedMessage>* /*mailbox*/) {
118 : : // Default no-op; EventBasedActor overrides this
119 : 0 : }
120 : :
121 : : } // namespace hpactor
|