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

"Realm accessed from incorrect thread" when called from JUCE Message Thread #235

Closed
adamski opened this issue Jul 30, 2024 · 6 comments
Closed

Comments

@adamski
Copy link

adamski commented Jul 30, 2024

Realm-cpp version 2.2.0

When processing a realm::results<T> object, from the message thread in a JUCE project, I get a LogicError exception with error code WrongThread and message "Realm accessed from incorrect thread."

Screenshot 2024-07-30 at 10 15 55

I'm not sure if this is a bug or intentional. If intentional, I'm not sure how to do the processing on the thread that Realm expects.

Copy link

sync-by-unito bot commented Jul 30, 2024

➤ PM Bot commented:

Jira ticket: RCPP-86

@leemaguire
Copy link
Contributor

Hey @adamski, I'm not familiar with how JUCE does things under the hood. Realm requires all operations to be done on the thread it was opened on, other wise you should use a thread safe reference. Did you initially open this realm instance on the main thread?

@adamski
Copy link
Author

adamski commented Jul 30, 2024

Thanks @leemaguire. I now realise what's going wrong. I made some changes to log in on a separate thread, and I'm setting up the realm instance if successful also on that thread. That explains the issue. I need to ensure that the realm instance is created asynchronously once the log in status changes. (I'm starting with a local realm and re-initialising to a synced realm once logged in).

@adamski
Copy link
Author

adamski commented Jul 30, 2024

For anyone else that comes across this issue, I solved it using the realm Scheduler class. I would normally use JUCE's AsyncUpdater but in this case I want to keep the code I'm writing framework agnostic.

            auto scheduler = realm::util::Scheduler::make_default();
            std::thread loginThread ([this, username, scheduler]()
                                     {
            try
            {
                std::future_status status;
                // TODO: Improve security with JWT based login
                std::string credentials = "{ \"username\": \"" + username + "\" }";

                std::cout << "Logging in..." << std::endl;
                auto userFuture = app->login (realm::App::credentials::function (credentials));
                std::cout << "Waiting for response" << std::endl;

                do
                {
                    switch (status = userFuture.wait_for (50ms); status)
                    {
                        case std::future_status::deferred:
                            std::cout << "deferred\n";
                            break;
                        case std::future_status::timeout:
                            std::cout << "timeout\n";
                            break;
                        case std::future_status::ready:
                            std::cout << "ready!\n";
                            break;
                    }
                } while (status != std::future_status::ready);

                user = userFuture.get();
                std::cout << "Logged in. User ID is " << user.identifier() << '\n';

                scheduler->invoke ([this]
                                   {
                                       setupSyncedRealm();
                                       setupSubscriptions();
                                       setupObservers();
                                   });
            }
            catch (const realm::app_error& e)
            {
                std::cout << "Error logging in: " << e.message() << std::endl;
                return;
            } });

            loginThread.detach();

@adamski
Copy link
Author

adamski commented Jul 31, 2024

I realised the code above is not working - the lambda passed to invoke is never executed. @leemaguire do you have any insight on that? If necessary I can move the async call elsewhere using a different technique, but the scheduler seems like a nice way to do it.

@adamski
Copy link
Author

adamski commented Jul 31, 2024

Closing this issue as it was user error, I'll open another one about the scheduler

@adamski adamski closed this as completed Jul 31, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 30, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants