Skip to content
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

RXI-893 Change owning model to guarantee destroying sequence #104

Merged
merged 3 commits into from
May 14, 2024

Conversation

oleks-rip
Copy link
Collaborator

No description provided.

Copy link
Contributor

@seelabs seelabs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not following how this is safe - it looks like destroyed objects could be accessed in asio during system shutdown. But I didn't dig in too deeply, I thought I'd ask for an explanation for why this is safe first.

The commit message is too terse. The commit message should explain why it is safe to make this change.

make_Federator(
App& app,
boost::asio::io_service& ios,
config::Config const& config,
ripple::Logs& l)
{
auto r = std::make_shared<Federator>(
auto r = std::make_unique<Federator>(
Federator::PrivateTag{}, app, config, l.journal("Federator"));
r->init(ios, config, l);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The motivation for the "make_Federator" and the separation of the constructor into a constructor and an init was to satisfy the constraints around "shared_from_this". If the shared pointers are going away, then this can be simplified.

Copy link
Collaborator Author

@oleks-rip oleks-rip May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is required quite a rewrites to make federator as object, and not a pointer, cause of the deferred initialization. Just don't want to make unnecessary changes.

@@ -69,7 +68,7 @@ class WebsocketClient : public std::enable_shared_from_this<WebsocketClient>
std::atomic_bool peerClosed_{true};

std::function<void(Json::Value const&)> onMessageCallback_;
std::atomic<std::uint32_t> nextId_{0};
std::atomic_uint32_t nextId_{0};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer the template versions of these functions, but also OK as-is.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are both in the code, so I refactor them when I see one.

timer_.expires_after(CONNECT_TIMEOUT);
timer_.async_wait([wptr](boost::system::error_code const& ec) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see several places where a shared or a weak pointer was replaced with a naked this in a callback. The motivation for the shared/weak pointers was to make sure we don't access a destroyed object in asio. For example, during shutdown, the app is destroyed before asio. Aren't we in danger of accessing destroyed objects?

Copy link
Collaborator Author

@oleks-rip oleks-rip May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now Chain listener wait for websocketclient destructor. And websocketclient destructor will cancel all the io operations, and wait for it. So when destructor finish, no pending operations left. Then federator waits for both chainlisteners, and app waits for federator. These changes are to be ensure that when we destroy the local object, it is actually destroyed and there are no side effects caused by callbacks from the io operations.

Websocket destructor will cancel io operations and wait for it, so
after destructor finished no pending tasks will remain. The pointers
that are passed to callbacks will always point to valid objects.
ChainListener now waits for websocketclient destructor, Federator
waits for both chainlisteners and App waits for Federator.
Copy link
Contributor

@seelabs seelabs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@oleks-rip oleks-rip merged commit 3ad0540 into ripple:develop May 14, 2024
@oleks-rip oleks-rip deleted the own_model branch May 14, 2024 21:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants