Neverlord on master
Replace Coverity badge with LGT… (compare)
Neverlord on master
Fix LGTM warnings Merge pull request #1223 Fix L… (compare)
Neverlord on neverlord
Neverlord on neverlord
Fix LGTM warnings (compare)
Neverlord on neverlord
Support variant types in json_r… (compare)
Neverlord on neverlord
Support variant fields in the j… (compare)
Neverlord on neverlord
Omit @type fields for nested ob… (compare)
Neverlord on neverlord
Neverlord on master
Add new example for variant-lik… (compare)
Neverlord on neverlord
Add missing include (compare)
Neverlord on neverlord
Remove 'using namespace caf' (compare)
I am still reading documentation what interests me is the core library as shared library for multiple OS/hardware.
As far my primitive understanding goes I/O would require work to utilize multiple UDP channels with re-transmigration logic. (I might be miss understanding abstraction)
From documentation:
"Messages that are sent via datagrams are limited to a maximum of 65.535 bytes which is used as a receive buffer size by CAF."
I think 65.535 should 65,535.
Hi, is there a way to "remote_spawn" a class-based event-based actor? The example code shows "remote_spawn" a function-based actor. When I tried to remote_spawn a class-based actor, I got an error that "no matching constructor for initialization" of the actor class.
To (local) spawn the class-based actor, I just need to simply provide a constructor taking "actor_config &" as first argument, but for "remote_spawn", the error message shows the first argument should be "actor_control_block *" instead of "actor_config &", but there is no constructor for event-based actor using "actor_control_block *". Can anyone help me? Thanks!
message
: https://github.com/actor-framework/actor-framework/blob/master/examples/remoting/remote_spawn.cpp#L136
add_actor_type<MyClass, A, B, C>("MyClass")
, where A
, B
and C
are the arguments required to instantiate this actor remotely.
Sure, the following is actor_system_config
I used in client and server side:
struct config : actor_system_config {
config(int port, std::string host, bool serverMode) :
port_(port), host_(host), serverMode_(serverMode){
load<io::middleman>();
add_actor_type<OperatorActor>("operator");
opt_group{custom_options_, "global"}
.add(port, "port,p", "set port")
.add(host, "host,H", "set node (ignored in server mode)")
.add(serverMode_, "server-mode,s", "enable server mode");
}
uint16_t port_;
std::string host_;
bool serverMode_;
};
where OperatorActor
is the class I wish to remote_spawn
, derived from event_based_actor
.
The following is the function I use to remote_spawn
:
caf::actor graph::OperatorGraph::remoteSpawn(const std::shared_ptr<Operator>& op) {
auto remoteSpawnTout = std::chrono::seconds(10);
auto expectedActorHandle = operatorManager_.lock()->getActorSystem()->middleman()
.remote_spawn<normal::core::OperatorActor>(node_.value(), "operator", make_message(), remoteSpawnTout);
if (!expectedActorHandle) {
throw std::runtime_error(fmt::format("Failed to remote-spawn operator actor '{}': {}", op->name(), to_string(expectedActorHandle.error())));
}
return caf::actor_cast<caf::actor>(expectedActorHandle.value());
}
where operatorManager_.lock()->getActorSystem()
gives the actor_system
of client side, node_value()
gives the remote node already connected.
The following is the compilation error I got:
.../caf/actor_cast.hpp:154:12: error: no matching constructor for initialization of 'normal::core::OperatorActor'
return {x.release(), false};
^~~~~~~~~~~~~~~~~~~~
.../caf/actor_cast.hpp:177:10: note: in instantiation of member function 'caf::actor_cast_access<normal::core::OperatorActor, caf::intrusive_ptr<caf::actor_control_block>, 6>::operator()' requested here
return f(std::forward<U>(what));
^
.../caf/io/middleman.hpp:167:12: note: in instantiation of function template specialization 'caf::actor_cast<normal::core::OperatorActor, caf::intrusive_ptr<caf::actor_control_block> >' requested here
return actor_cast<Handle>(std::move(*res));
^
.../caf/io/middleman.hpp:175:12: note: in instantiation of function template specialization 'caf::io::middleman::remote_spawn<normal::core::OperatorActor>' requested here
return remote_spawn<Handle>(nid, std::move(name), std::move(args),
^
.../graph/OperatorGraph.cpp:165:12: note: in instantiation of function template specialization 'caf::io::middleman::remote_spawn<normal::core::OperatorActor, long long, std::__1::ratio<1, 1> >' requested here
.remote_spawn<normal::core::OperatorActor>(node_.value(), "operator", make_message(), remoteSpawnTout);
^
.../OperatorActor.h:36:3: note: candidate constructor not viable: no known conversion from 'caf::intrusive_ptr<caf::actor_control_block>::pointer' (aka 'caf::actor_control_block *') to 'caf::actor_config &' for 1st argument
OperatorActor(caf::actor_config &cfg, std::shared_ptr<Operator> opBehaviour);
^
.../OperatorActor.h:25:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
class OperatorActor : public caf::event_based_actor {
^
The constructor of OperatorActor
is the following:
OperatorActor::OperatorActor(caf::actor_config &cfg, std::shared_ptr<Operator> opBehaviour) :
caf::event_based_actor(cfg),
opBehaviour_(std::move(opBehaviour)) {
name_ = opBehaviour_->name();
}
which is used when spawn
actors locally. It seems not a fit for remote_spawn
which I'm unsure how to adjust. Hope this can help :), thanks!
add_actor_type<OperatorActor, std::shared_ptr<Operator>>("operator");
. There's also a potential issue with sending a shared_ptr
. CAF generally allows this, but be aware that you won't have a good time if Operator
is a base type and you'll actually want to serialize/deserialize derived types. That won't work out of the box and you'd have to implement inspect
functions that know the full class hierarchy.
Thanks, now I change to add_actor_type<OperatorActor, std::shared_ptr<Operator>>("operator");
, but the compilation error is still there, which I guess the main error is:
.../OperatorActor.h:36:3: note: candidate constructor not viable: no known conversion from 'caf::intrusive_ptr<caf::actor_control_block>::pointer' (aka 'caf::actor_control_block *') to 'caf::actor_config &' for 1st argument
OperatorActor(caf::actor_config &cfg, std::shared_ptr<Operator> opBehaviour);
^
perhaps my constructor also needs to be modified accordingly, but I'm stuck at this caf::actor_control_block *
from the error. :(
caf::actor
for dynamically typed actors or caf::typed_actor<...>
for statically typed actors.
event_based_actor
, than you need to pass caf::actor
here.
Yeah OperatorActor
is my class deriving event_based_actor
, but I'm unsure how to get the handle type from my OperatorActor
. I tried OperatorActor::event_based_actor
as the following:
auto expectedActorHandle = operatorManager_.lock()->getActorSystem()->middleman()
.remote_spawn<OperatorActor::event_based_actor>(node_.value(), "operator", make_message(), remoteSpawnTout);
seemed to solve the error of constructor, but it gave 4 other errors, the first one is:
.../caf/actor_cast.hpp:62:36: error: no member named 'has_weak_ptr_semantics' in 'caf::event_based_actor'
static constexpr bool value = T::has_weak_ptr_semantics;
~~~^
.../caf/actor_cast.hpp:168:44: note: in instantiation of static data member 'caf::(anonymous namespace)::is_weak_ptr<caf::event_based_actor>::value' requested here
constexpr bool to_weak = is_weak_ptr<T>::value;
^
.../caf/io/middleman.hpp:167:12: note: in instantiation of function template specialization 'caf::actor_cast<caf::event_based_actor, caf::intrusive_ptr<caf::actor_control_block> >' requested here
return actor_cast<Handle>(std::move(*res));
^
.../caf/io/middleman.hpp:175:12: note: in instantiation of function template specialization 'caf::io::middleman::remote_spawn<caf::event_based_actor>' requested here
return remote_spawn<Handle>(nid, std::move(name), std::move(args),
^
.../OperatorGraph.cpp:166:12: note: in instantiation of function template specialization 'caf::io::middleman::remote_spawn<caf::event_based_actor, long long, std::__1::ratio<1, 1> >' requested here
.remote_spawn<OperatorActor::event_based_actor>(node_.value(), "operator", make_message(), remoteSpawnTout);
maybe it's not the right way to get the handle type?
add_actor_type<MyClass, A, B, C>("operator");
, where should parameters a, b, c
of type A, B, C
be passed when calling remote_spawn
? like when spawn
locally we can actor_system.spawn<MyClass>(a, b, c)
. remote_spawn
has 4 parameters node_id, name, message, timeout
, all seems to be fixed.
Operator
, where I have classes deriving it).add_message_type
of this abstract Operator
, or all deriving types one by one?inspect
for all deriving types, is this correct?
variant
-based approach instead. Otherwise, you'd have to keep track of the class hierarchy in your inspect
overloads and dispatch accordingly during deserialization. There's not "the way" to do it, though. Depends on whether you are dealing with a sealed class hierarchy (in which case you probably can switch to a variant
or at least treat your type as such) or if you want it to remain extensible (then you need some kind of registry/factory interface).
shared_ptr
, I guess CAF generally allows it right? (guess you mentioned it but seems I didn't fully get it :/). It always yields a nullptr
during deserialization at the remote node. Maybe inspect
shared_ptr
variables need some changes from common objects?inspect
functions seem not to be used when (de)serializing their shared_ptr
s.
inspect
overload you implement now is already obsolete because the inspection API changed.struct tick_actor_state {
tick_actor_state(caf::event_based_actor* self, caf::actor worker)
: self(self) hdl(caf::actor_cast<caf::actor_addr>(worker)) {
// nop
}
caf::behavior make_behavior() {
using std::chrono_literals;
self->scheduled_send(self, 1s, caf::tick_atom_v);
return {
[](caf::tick_atom) {
if (auto sref = caf::actor_cast<caf::actor>(hdl)) {
self->send(sref, caf::tick_atom_v);
self->scheduled_send(self, 1s, caf::tick_atom_v);
}
}
};
}
caf::event_based_actor* self;
caf::actor_addr hdl;
};
variant<none_t, circle, rectangle>
, but it should give you a starting point.
master
now: https://github.com/actor-framework/actor-framework/blob/master/examples/custom_type/custom_types_4.cpp