-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rust integration: Adding variables & clients. #102
Conversation
3a76180
to
9cf60a7
Compare
@hikinggrass Kai, could you run clang-format for me again, please? I still do not have access to a Linux dev machine. Update: Figured it out. |
We updated also EVerest/everest-core#344 to work with this new code. |
847a985
to
157efa7
Compare
@hikinggrass @a-w50 Friendly ping? This has been sitting for a week now. |
I'm still working on the cmake integration, but I hope to have something to push sometime today |
17935bc
to
be7eab6
Compare
This (in combination with the changes I just pushed on everest-core) should allow rust modules to be built with cmake without having to manually specify the location of everest-framework or to rely on heuristics. There have been some changes to the config handling in everest-framework recently which I've already rebased against. One thing I've noticed with the rust modules in general: it looks like they do not yet publish true to everest/<module_id>/ready once their initialization code has run and triggering this manually doesn't seem to call the on_ready handler yet. That's probably something we should fix before merging this as well. |
everestrs/everestrs/src/lib.rs
Outdated
pub fn set_subscriber(&self, sub_impl: Weak<dyn Subscriber>) { | ||
*self.sub_impl.write().unwrap() = Some(sub_impl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from an api perspective, set_subscriber
can only be called once, right? If so, this should belong into the constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The better place would be the ctor but for our user facing api we have following dependencies
- The publishers need a ref to the runtime
- the subscribers need a ref to the publishers
- The runtime needs a ref to the subscribers.
to brake this vicious cycle we pass the subscribers after the construction to the runtime
have a look at the core or for how it works together
everestrs/everestrs/src/lib.rs
Outdated
self.cpp_module | ||
.as_ref() | ||
.unwrap() | ||
.provide_command(self, implementation_id.clone(), name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: The runtime (self) is passed here via provide_command
. Are rust references direct pointers, i.e. do they point to a specific memory location? If so, this makes the Runtime class non-moveable, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point. But we have to pin not the subscriber reference but the runtime. The cxx bridge and set_subscribers should probably take Pin since this is the point from which we aren’t allowed to move. By not implementing Unpin we make sure that the runtime remains pinned once the set_subscriber is called
return json::parse(blob.data.begin(), blob.data.end()); | ||
}); | ||
} | ||
|
||
void Module::subscribe_variable(const Runtime& rt, rust::String implementation_id, rust::String name) const { | ||
// TODO(hrapp): I am not sure how to model the multiple slots that could theoretically be here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SirVer : what do you mean by multiple slots?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@a-w50 I mean that num_connections != 1
for this implementation_id
. I did not understand the C++ code around this, hence I did not model it in Rust at all currently. My understanding is that the c++ code initially assumed that there would only be one connection, but then this was extendended to allow for more than one connection. To me this is a topic that needs addressing, but can be done at a later point. I also need a clinic where somebody explains this to me (or @dorezyuk, whoever implements this for rust).
@@ -7,6 +7,10 @@ struct Libraries { | |||
} | |||
|
|||
fn find_everest_workspace_root() -> PathBuf { | |||
if let Ok(everest_framework_dir) = env::var("EVEREST_RS_FRAMEWORK_SOURCE_LOCATION") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming is a bit off here, is it everest framework dir OR everestrs framework source location?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intention with naming here was that this environment variable is meant for everestrs and contains the location to the source of everest-framework
if let Ok(everest_framework_dir) = env::var("EVEREST_RS_FRAMEWORK_BINARY_LOCATION") { | ||
let everest_framework_path = PathBuf::from(everest_framework_dir); | ||
( | ||
everest_framework_path.join("everestrs/libeverestrs_sys.a"), | ||
everest_framework_path.join("lib/libframework.so"), | ||
) | ||
} else { | ||
( | ||
root.join("everest-framework/build/everestrs/libeverestrs_sys.a"), | ||
root.join("everest-framework/build/lib/libframework.so"), | ||
) | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure about rust best practices, but for me this if let Ok(..) = ... {
doesn't naturally read. Also the implicit returns are hard to spot (but could just be me ...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'd prefer a match statement here too. The implicit returns are rustic - i.e. idiomatic. They are like meaningful whitespace in Python - one first finds them appalling, once used to them they become rather nice.
let everestrs_sys = root.join("everest-framework/build/everestrs/libeverestrs_sys.a"); | ||
let framework = root.join("everest-framework/build/lib/libframework.so"); | ||
let (everestrs_sys, framework) = | ||
if let Ok(everest_framework_dir) = env::var("EVEREST_RS_FRAMEWORK_BINARY_LOCATION") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compare the naming:
if let Ok(everest_framework_dir) = env::var("EVEREST_RS_FRAMEWORK_SOURCE_LOCATION") {
and
if let Ok(everest_framework_dir) = env::var("EVEREST_RS_FRAMEWORK_BINARY_LOCATION") {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we do need the binary location here, not the source location, which are usually not identical
let everestrs_sys = root.join("everest-framework/build/everestrs/libeverestrs_sys.a"); | ||
let framework = root.join("everest-framework/build/lib/libframework.so"); | ||
let (everestrs_sys, framework) = | ||
if let Ok(everest_framework_dir) = env::var("EVEREST_RS_FRAMEWORK_BINARY_LOCATION") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you pass locations by environment variables, why don't you pass the the complete path to libeverestrs_sys.a
and libframework.so
directly, this would be more stable. Note that at least inside cmake you can get the full path to library-targets (using generator expressions: FRAMEWORK_LIB=$<TARGET_FILE:everest::framework>
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely, would add yet another environment variable but I guess the cost of that is quite low
src/manager.cpp
Outdated
@@ -199,6 +200,26 @@ static SubprocessHandle exec_cpp_module(const ModuleStartInfo& module_info, std: | |||
return handle; | |||
} | |||
|
|||
static SubprocessHandle exec_rust_module(const ModuleStartInfo& module_info, std::shared_ptr<RuntimeSettings> rs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is really no point here in passing the RuntimeSettings
as shared pointer, just pass it as a (ideally const) reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment this is just to keep it in line with the other exec_* functions, I would suggest we refactor this in a new PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a TODO then for now so we do not forget? Reference this MR for posterity.
I did a flyby of the code, I have little time this week, so might not be able to dive deeper - thanks for the work and review so far! |
af1c7fb
to
31c92f8
Compare
@hikinggrass What is this still waiting on? |
Co-authored-by: Dima Dorezyuk <ddo@qwello.eu> Signed-off-by: Holger Rapp <hra@qwello.eu> Signed-off-by: Holger Rapp <HolgerRapp@gmx.net>
Signed-off-by: Holger Rapp <HolgerRapp@gmx.net>
Signed-off-by: Holger Rapp <HolgerRapp@gmx.net>
Signed-off-by: Kai-Uwe Hermann <kai-uwe.hermann@pionix.de>
Signed-off-by: Kai-Uwe Hermann <kai-uwe.hermann@pionix.de>
Signed-off-by: Kai-Uwe Hermann <kai-uwe.hermann@pionix.de>
Signed-off-by: Kai-Uwe Hermann <kai-uwe.hermann@pionix.de>
Signed-off-by: Kai-Uwe Hermann <kai-uwe.hermann@pionix.de>
Signed-off-by: aw <aw@pionix.de>
- clean target still needs to be fixed Signed-off-by: aw <aw@pionix.de>
Signed-off-by: Kai-Uwe Hermann <kai-uwe.hermann@pionix.de>
c7ff891
to
14b5a1b
Compare
just a rebase, I'm squashing right now :) |
❤️ ❤️ 🎆 H O O R A Y 🚀 ❤️ ❤️ |
Co-authored-by: Dima Dorezyuk ddo@qwello.eu
Signed-off-by: Holger Rapp hra@qwello.eu