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

Update BindingCallbackThreadObserver to be one per sync client #6156

Merged
merged 31 commits into from
Feb 24, 2023

Conversation

michael-wb
Copy link
Contributor

@michael-wb michael-wb commented Dec 30, 2022

What, How & Why?

The BindingCallbackThreadObserver was originally a global instance that was shared across all sync client/default socket provider instances. The changes in this PR move the BindingCallbackThreadObserver to be a shared_ptr parameter in the SyncClientConfig, which allows for either a single instance to be shared across all sync clients or a unique instance per sync client. The observer class was also updated to allow optional implementations for the three functions, instead of a base class that required all three functions to be implemented.

In addition, a C API test was added for the BindingCallbackThreadObserver to verify its operation (and some updates to the interface were needed).

NOTE: The BindingCallbackThreadObserver is only used by the default sync socket provider implementation. It is up to custom sync socket provider implementations to add their own support for threaded callbacks.

Fixes #6250

☑️ ToDos

  • 📝 Changelog update
  • 🚦 Tests (or not relevant)
  • C-API, if public C++ API changed.

@cla-bot cla-bot bot added the cla: yes label Dec 30, 2022
@michael-wb michael-wb marked this pull request as ready for review December 30, 2022 21:02
@michael-wb michael-wb linked an issue Jan 3, 2023 that may be closed by this pull request
@michael-wb michael-wb self-assigned this Jan 3, 2023
@michael-wb michael-wb force-pushed the mwb/event-loop-migration branch 2 times, most recently from 992b676 to 1b738ce Compare January 13, 2023 06:52
@michael-wb michael-wb force-pushed the mwb/event-loop-migration branch 2 times, most recently from 3d1b750 to f49ac5b Compare January 19, 2023 13:46
@michael-wb michael-wb marked this pull request as draft January 20, 2023 21:03
Base automatically changed from mwb/event-loop-migration to master January 26, 2023 00:03
@michael-wb michael-wb marked this pull request as ready for review January 26, 2023 21:36
Copy link
Collaborator

@danieltabacaru danieltabacaru left a comment

Choose a reason for hiding this comment

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

CI reports a data race in Sync_MultipleSyncAgentsNotAllowed. LGTM otherwise

@danieltabacaru
Copy link
Collaborator

There are some bootstrap tests failing. Are they related to these changes?

@michael-wb
Copy link
Contributor Author

There are some bootstrap tests failing. Are they related to these changes?

I believe these (and the data race) failures are fixed in Jonathans PRs, #6244 and #6216(already merged) - I will wait to merge until his changes are merged to verify these are fixed.

@michael-wb
Copy link
Contributor Author

There are some bootstrap tests failing. Are they related to these changes?

I believe these (and the data race) failures are fixed in Jonathans PRs, #6244 and #6216(already merged) - I will wait to merge until his changes are merged to verify these are fixed.

Turns out it was a valid data race - I updated the test similar to how Jonathan updated other tests in test_sync.cpp to define the DefaultSocketProvider separately so stop() could be called manually. Now the test is passing.

@@ -185,6 +186,10 @@ struct ClientConfig {
// and creating WebSockets. If not provided the default implementation will be used.
std::shared_ptr<sync::SyncSocketProvider> socket_provider;

// Optional thread observer for event loop thread events in the default SyncSocketProvider
// implementation. It is not used for custom SyncSocketProvider implementations.
std::shared_ptr<BindingCallbackThreadObserver> default_socket_provider_thread_observer;
Copy link
Contributor

Choose a reason for hiding this comment

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

does this really need shared lifetime management? could we just use a unique_ptr here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It could technically just be a unique_ptr, since the SyncClientConfig is required for each start of the sync client. The main question is whether the SDK would prefer to use a single shared ptr across all the apps or is it fine to define a separate observer instance for each app. @cmelchior, any preferences?

virtual ~BindingCallbackThreadObserver() = default;

// Set the global thread observer with the provided (optional) callback functions
static void set_global_thread_observer(std::unique_ptr<BindingCallbackThreadObserver>&& observer_ptr)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we really need to keep the old global API here? Currently this is used by just one SDK. @cmelchior, is adopting the new per-app API sufficiently complicated for java that we should support both APIs for now?

Copy link
Contributor

Choose a reason for hiding this comment

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

No, it shouldn't be complicated. Removing this is fine 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK - I'll remove the global support and update the CAPI.

@@ -507,6 +510,10 @@ void DefaultSocketProvider::start()

m_logger_ptr->trace("Default event loop: start()");
REALM_ASSERT(m_state == State::Stopped);

// Reset the service so it can be run() again
m_service.reset();
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this ever actually needed? Currently the default socket provider is only used once, except in testing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was only for completeness if the default socket provider ever needed to be restarted. I can remove it.

@jbreams
Copy link
Contributor

jbreams commented Feb 6, 2023 via email

@michael-wb michael-wb changed the title Add event loop error handler for testing Update BindingCallbackThreadObserver so it is one per sync client Feb 24, 2023
@michael-wb michael-wb changed the title Update BindingCallbackThreadObserver so it is one per sync client Update BindingCallbackThreadObserver to be one per sync client Feb 24, 2023
@michael-wb
Copy link
Contributor Author

michael-wb commented Feb 24, 2023 via email

src/realm.h Outdated
* @param user_data pointer to user defined data that is provided to each of the callback functions
* @param free_userdata callback invoked when the user_data is to be freed
*/
RLM_API void realm_sync_client_config_set_default_binding_thread_observer(
Copy link
Contributor

Choose a reason for hiding this comment

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

I thought we decided to just have the per-app version...

void BindingCallbackThreadObserver::call_will_destroy_thread(
const std::shared_ptr<BindingCallbackThreadObserver>& observer_ptr)
{
// Call into the observer ptr if not null, otherwise, use the global thread observer
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like there is no global observer? Do we still need these static functions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These were just helper functions... I'll remove them and just use the direct function calls in the default socket provider.

@michael-wb michael-wb merged commit 09381ba into master Feb 24, 2023
@michael-wb michael-wb deleted the mwb/event-loop-error-handler branch February 24, 2023 18:59
@kiburtse kiburtse mentioned this pull request Mar 3, 2023
3 tasks
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 21, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add per app support for BindingCallbackThreadObserver
4 participants