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

onAuthorizer hangs iOS app #34

Closed
barsumek opened this issue Sep 20, 2022 · 3 comments
Closed

onAuthorizer hangs iOS app #34

barsumek opened this issue Sep 20, 2022 · 3 comments

Comments

@barsumek
Copy link

Problem

onAuthorizer callback must be used if one wants to implement a more complex auth logic (e.g. pass auth token as a request's header).
It is an asynchronous callback, meaning it can take time, depending on the user's network/server's load etc.
During this time the app should be responsive, so the user is able to interact with it and e.g. change the screen in the app.

However, currently onAuthorizer hangs the app until the necessary object is returned back through React Native bridge.
As a result, the app becomes unresponsive during authorization.

Repro steps:

  1. Install example app from this pusher repo, commit b65a2c5fd885a2be4b1e9d1cbf9e8f5183622ef5
  2. Simulate long async operation in the code:
// modify onAuthorizer implementation to this:
const onAuthorizer = async (channelName: string, socketId: string) => {
    // this could also be any await fetch(url), but long timeout is better for repro
    await new Promise((resolve) => setTimeout(resolve, 10000));
  1. Add extra button to test tap interaction during onAuthorizer a bit easier
<Image style={styles.image} source={require('./pusher.png')} />
<Button title="Click me" /> {/* Add this line for testing tap interaction */}
  1. Start the app, fill in Pusher text inputs (remember to use private- channel prefix to trigger auth!), confirm that the app is interactive - the new button works, the text inputs are clickable
  2. Tap Connect button and try tapping the new button

Expectation: the button can be tapped
Actual: the button doesn't do anything during await or stays in "tapped" state if one taps it right before onAuthorizer triggers, proving the app hangs

Video of the reproduction

HangExample.mov

Some extra notes

I debugged this a bit and it looks like the culprit is the usage of mutex for onAuthorizer.

In the Pusher RN code this line:
authorizerMutex[key]!.wait()
blocks the main thread, preventing further interaction until JS thread calls onAuthorizer.

Similarly, if we change the code in JS:

return {
      auth: pusherKey + ':' + signature,
      channel_data: user,
      shared_secret: 'foobar',
};

to e.g. simple return; or return undefined;, then the app will hang as well and never unblock itself.
It seems a bit risky and easy to miss, especially since Typescript types specify onAuthorizer return type as any.

Generally, the usage of mutex in React Native modules is not that common – I wonder if it would be possible to change this logic to something less blocking and avoid further app hangs.

@proggen-com
Copy link
Contributor

proggen-com commented Sep 21, 2022

Yes this is a bit tricky, it's a blocking construct. let's think about making this async, it probably needs bidirectional events with a timeout handler etc.

@fbenevides
Copy link
Contributor

Released 1.2.0, which fixes this issue. Thanks for your contribution @barsumek 🚀

@mohamedanwermohamed
Copy link

i have same problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants