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

Xcode 14.0 beta 4 reports "Hang Risk" in RCTWebSocket #34400

Closed
lucasjohnston opened this issue Aug 12, 2022 · 45 comments
Closed

Xcode 14.0 beta 4 reports "Hang Risk" in RCTWebSocket #34400

lucasjohnston opened this issue Aug 12, 2022 · 45 comments

Comments

@lucasjohnston
Copy link

Description

Error reported: Thread running at QOS_CLASS_USER_INTERACTIVE waiting on a lower QoS thread running at QOS_CLASS_DEFAULT. Investigate ways to avoid priority inversions.
Using Xcode Version 14.0 beta 4 (14A5284g).

Screenshot 2022-08-12 at 17 44 11

Seemingly originates from RCTSRWebSocket.m

Version

0.66.3

Output of npx react-native info

info Fetching system and libraries information...
System:
OS: macOS 12.5
CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 186.13 MB / 16.00 GB
Shell: 5.8 - /usr/local/bin/zsh
Binaries:
Node: 14.17.1 - ~/.nvm/versions/node/v14.17.1/bin/node
Yarn: 1.22.10 - ~/src/github.com/umbermoney/daisy/node_modules/.bin/yarn
npm: 6.14.13 - ~/.nvm/versions/node/v14.17.1/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.10.1 - /Users/lucas/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms: DriverKit 21.4, iOS 15.4, macOS 12.3, tvOS 15.4, watchOS 8.5
Android SDK:
API Levels: 21, 28, 29, 30
Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.2
System Images: android-29 | Google APIs Intel x86 Atom, android-31 | Google APIs Intel x86 Atom_64
Android NDK: Not Found
IDEs:
Android Studio: 2021.2 AI-212.5712.43.2112.8609683
Xcode: 13.3/13E113 - /usr/bin/xcodebuild
Languages:
Java: 1.8.0_251 - /Users/lucas/.jenv/shims/javac
npmPackages:
@react-native-community/cli: Not Found
react: 17.0.2 => 17.0.2
react-native: 0.66.3 => 0.66.3
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found

Steps to reproduce

  1. Create react-native project on Xcode Version 14.0 beta 4 (14A5284g)
  2. Run application

Snack, code example, screenshot, or link to a repository

dispatch_group_wait(_waitGroup, DISPATCH_TIME_FOREVER);

@titanium-cranium
Copy link

Any movement on this? Our app is similarly hamstrung after upgrade to iOS16

@Quadrified
Copy link

Quadrified commented Sep 29, 2022

Facing the same issue on iOS 15.x and iOS 16 on Xcode 14.0.1
Any alternate fix to at least patch this issue until we wait for a permanent fix?

@xuannam12
Copy link

xuannam12 commented Sep 30, 2022

Try clone the new repo for your project!

@muhabutt
Copy link

Facing the same issue on iOS 15.x and iOS 16 on Xcode 14.0.1. I think there is something wrong with the generated FBReactNativeSpec code.

@hamzasohail
Copy link

This falls under the same category as discussed here: realm/realm-core#5697

The difference is that this inversion is triggered by a dispatch group but it's the same problem -- the threads in the dispatch group are not running at a QoS higher than "Default". For folks who work on Websocket, there are resolution strategies mentioned in realm/realm-core#5697.

@costea93
Copy link

costea93 commented Oct 5, 2022

any updates on this?

@muhabutt
Copy link

Any updates on this issue, I can reproduce this bug on Fresh react native 0.70.2.

@bodrius
Copy link

bodrius commented Oct 19, 2022

the same error

@xiongxiongjiang
Copy link

same error

@xiongxiongjiang
Copy link

node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.m:1632: warning run: Thread running at QOS_CLASS_USER_INTERACTIVE waiting on a lower QoS thread running at QOS_CLASS_DEFAULT. Investigate ways to avoid priority inversions
at:

- (NSRunLoop *)runLoop
{
  dispatch_group_wait(_waitGroup, DISPATCH_TIME_FOREVER);
  return _runLoop;
}

@alessioemireni
Copy link

+1

@george-bafaloukas-forgerock

+1 This seems present on a Fresh RN upgrade

@mmelk
Copy link

mmelk commented Oct 31, 2022

+1 I cannot connect to the Web Socket in the useEffect() triggered by App State after returning from background state
Need to move to the other view and back to refresh my app

Xcode 14.0.1

@SmileYang966
Copy link

+1 who can help to fix this issue?

@xclidongbo
Copy link

same error

@c-shimmer
Copy link

+1

@xueqiulou
Copy link

is there any solution?

@JeffGuKang
Copy link
Contributor

Hey guys. Please upvote to the original post instead of adding a +1 comment if you have the same problem or interest this post.

@clemente-xyz
Copy link

having exactly the same issue. Any updates?

@rmoura-92
Copy link

this just popped to me today after running a pod install

@rmoura-92
Copy link

rmoura-92 commented Nov 9, 2022

Screenshot 2022-11-09 at 15 34 21
this worked for me as temp measure

described here https://developer.apple.com/documentation/xcode/diagnosing-performance-issues-early

@voloshink
Copy link

Screenshot 2022-11-09 at 15 34 21 this worked for me

described here https://developer.apple.com/documentation/xcode/diagnosing-performance-issues-early

You just turned off the checker, that doesn't mean the underlying issue is solved.

@bjornmosten
Copy link

I got this too. XCode 14.1. RN 0.69.5
Is anyone actually experiencing any problems from this? Could it be a pre-existing non-issue that XCode just started complaining about?

@hamzasohail
Copy link

hamzasohail commented Nov 15, 2022

I don't work on React but as I mentioned in my comment above, this issue is pointing to a priority inversion. Priority inversions won't crash your program but can cause performance issues especially when system is under heavy resource contention. This inversion is coming from the React framework itself. Folks who maintain the React framework should audit their usage of dispatch_group_wait -- it's a primitive that doesn't provide priority inversion avoidance.The link (https://developer.apple.com/documentation/xcode/diagnosing-performance-issues-early) explains how these inversions should be addressed.

As for app developers who are seeing this (because they are using React), they should keep an eye on whether this inversion is causing hangs in their app for their app users. If it is, you probably want to deep dive more in the architecture of your app to avoid this inversion.

@matthewmturner
Copy link

I started having this issue out of the blue. Originally I think it came up when adding a new dependency (react-native-mixpanel) but now im having the issue on all my branches, even without that dep.

@Crare
Copy link

Crare commented Dec 12, 2022

I get this same error only when running to device. Not happening when building to an iPhone simulator.

System:
OS: macOS 12.5.1
CPU: (10) arm64 Apple M1 Max
Memory: 3.67 GB / 32.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 19.2.0 - /opt/homebrew/bin/node
Yarn: 1.22.19 - /opt/homebrew/bin/yarn
npm: 9.2.0 - /opt/homebrew/bin/npm
Watchman: 2022.12.05.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: Not Found
SDKs:
iOS SDK:
Platforms: DriverKit 22.1, iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1
Android SDK: Not Found
IDEs:
Android Studio: 2021.3 AI-213.7172.25.2113.9123335
Xcode: 14.1/14B47b - /usr/bin/xcodebuild
Languages:
Java: Not Found
npmPackages:
@react-native-community/cli: Not Found
react: 18.1.0 => 18.1.0
react-native: 0.70.6 => 0.70.6
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found

@jbb-dev
Copy link

jbb-dev commented Dec 19, 2022

I had the same problem ( and I finally fixed it without really knowing why..., probably an indexing issue from XCODE 14).

If may be it can help you, these are the steps I follow :
1) I cleaned the build folder from XCODE (Product > Clean Build Folder)
2) I removed the DerivedData folder in ~/Library/Developer/Xcode/DerivedData
3) I restarted my computer

After that, I opened my app workspace from XCODE, a file indexing process started and took a very long time (something like 15 or 20 minutes).

Once indexing process finished, I tried to build again and VOILA, this time it worked !

I really hope it will help you.

Regards,

Jean-Baptiste

My system:
OS: macOS 12.6 Monterey
CPU: 1.8 GHz Intel Core i5
Memory: 8 GB 1600 Mhz DDR3
Node : v16.17.1
Xcode: 14.0.1
React: 18.1.0
React-native: 0.70.6

@rezkiy37
Copy link

I had the same problem ( and I finally fixed it without really knowing why..., probably an indexing issue from XCODE 14).

If may be it can help you, these are the steps I follow : 1) I cleaned the build folder from XCODE (Product > Clean Build Folder) 2) I removed the DerivedData folder in ~/Library/Developer/Xcode/DerivedData 3) I restarted my computer

After that, I opened my app workspace from XCODE, a file indexing process started and took a very long time (something like 15 or 20 minutes).

Once indexing process finished, I tried to build again and VOILA, this time it worked !

I really hope it will help you.

Regards,

Jean-Baptiste

My system: OS: macOS 12.6 Monterey CPU: 1.8 GHz Intel Core i5 Memory: 8 GB 1600 Mhz DDR3 Node : v16.17.1 Xcode: 14.0.1 React: 18.1.0 React-native: 0.70.6

Thank you!
It works for me!

@RubenPM-dev
Copy link

RubenPM-dev commented Jan 20, 2023

I had the same problem ( and I finally fixed it without really knowing why..., probably an indexing issue from XCODE 14).

If may be it can help you, these are the steps I follow : 1) I cleaned the build folder from XCODE (Product > Clean Build Folder) 2) I removed the DerivedData folder in ~/Library/Developer/Xcode/DerivedData 3) I restarted my computer

After that, I opened my app workspace from XCODE, a file indexing process started and took a very long time (something like 15 or 20 minutes).

Once indexing process finished, I tried to build again and VOILA, this time it worked !

I really hope it will help you.

Regards,

Jean-Baptiste

My system: OS: macOS 12.6 Monterey CPU: 1.8 GHz Intel Core i5 Memory: 8 GB 1600 Mhz DDR3 Node : v16.17.1 Xcode: 14.0.1 React: 18.1.0 React-native: 0.70.6

Thanks @jbb-dev

For those looking for the derivedData folder, from Xcode 6 you can find the path under ~/Users/YOUR_USERNAME/Library/Developer/Xcode/DerivedData

Also you can go to Xcode's settings and on the locations tab you can see your derived data path.

The folder is hidden, make sure to press Shift + Cmd + . to show the hidden folders.

@xueqiulou
Copy link

xueqiulou commented Jan 20, 2023 via email

@Sharf8351
Copy link

I had the same problem ( and I finally fixed it without really knowing why..., probably an indexing issue from XCODE 14).

If may be it can help you, these are the steps I follow : 1) I cleaned the build folder from XCODE (Product > Clean Build Folder) 2) I removed the DerivedData folder in ~/Library/Developer/Xcode/DerivedData 3) I restarted my computer

After that, I opened my app workspace from XCODE, a file indexing process started and took a very long time (something like 15 or 20 minutes).

Once indexing process finished, I tried to build again and VOILA, this time it worked !

I really hope it will help you.

Regards,

Jean-Baptiste

My system: OS: macOS 12.6 Monterey CPU: 1.8 GHz Intel Core i5 Memory: 8 GB 1600 Mhz DDR3 Node : v16.17.1 Xcode: 14.0.1 React: 18.1.0 React-native: 0.70.6

I tried this but it didn't work for me.

@xueqiulou
Copy link

xueqiulou commented Feb 19, 2023 via email

@Arnoldnuo
Copy link

Any progress or solution? My app with vlc player hangs constantly, but I cannot find why.

@limeup-team
Copy link

same issue even on a fresh rn project without any code changes xcode 14.0.1

@tido64
Copy link
Collaborator

tido64 commented Mar 17, 2023

FWIW, elevating the thread priority suppresses the priority inversion warning:

diff --git a/Libraries/WebSocket/RCTSRWebSocket.m b/Libraries/WebSocket/RCTSRWebSocket.m
index 925596f8677..a6244fb677e 100644
--- a/Libraries/WebSocket/RCTSRWebSocket.m
+++ b/Libraries/WebSocket/RCTSRWebSocket.m
@@ -1688,6 +1688,7 @@ static NSRunLoop *networkRunLoop = nil;
   dispatch_once(&onceToken, ^{
     networkThread = [_RCTSRRunLoopThread new];
     networkThread.name = @"com.squareup.SocketRocket.NetworkThread";
+    networkThread.qualityOfService = NSQualityOfServiceUserInteractive;
     [networkThread start];
     networkRunLoop = networkThread.runLoop;
   });

I have no idea whether this doesn't negatively affects anything else as I have no clue what it is used for.

That said, it looks like this module has recently been replaced: #36471

@amgleitman
Copy link

That said, it looks like this module has recently been replaced: #36471

Yep. If we wanted to apply this fix right now, the proper place would be in SocketRocket's SRRunLoopThread.m.

@Wxm510846302
Copy link

//
// Copyright 2012 Square Inc.
// Portions Copyright (c) 2016-present, Facebook, Inc.
//
// All rights reserved.
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
//

#import "SRRunLoopThread.h"
#import <pthread.h>
@interface SRRunLoopThread ()
{
dispatch_group_t _waitGroup;
}

@Property (nonatomic, strong, readwrite) NSRunLoop *runLoop;
@Property (strong, nonatomic) NSLock *lock1;
@Property (assign, nonatomic) pthread_mutex_t lock;
@Property (assign, nonatomic) pthread_cond_t cond;
@EnD

@implementation SRRunLoopThread

  • (void)dealloc {
    // 不用需要销毁
    pthread_mutex_destroy(&_lock);
    pthread_cond_destroy(&_cond);
    }

  • (void)__initMutex:(pthread_mutex_t *)mutex {
    // #define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MUTEX_SIG_init, {0}}
    // self.mutex = PTHREAD_MUTEX_INITIALIZER;

    // 静态初始化方法,所以这里不能用这种方式初始化,用下面👇🏻方法初始化
    // 1.初始化属性
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    /*

    • Mutex type attributes
      */
      // #define PTHREAD_MUTEX_NORMAL 0
      // #define PTHREAD_MUTEX_ERRORCHECK 1
      // #define PTHREAD_MUTEX_RECURSIVE 2
      // #define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL

    // pthread_mutexattr_settype(&attr, NULL); 传空,默认 PTHREAD_MUTEX_DEFAULT
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

    // 2.初始化锁
    pthread_mutex_init(mutex, &attr);

    // 3.销毁属性
    pthread_mutexattr_destroy(&attr);

    // 初始化条件
    pthread_cond_init(&_cond, NULL);

    pthread_mutex_lock(mutex);
    }

  • (instancetype)sharedThread
    {
    static SRRunLoopThread *thread;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    thread = [[SRRunLoopThread alloc] init];
    thread.name = @"com.facebook.SocketRocket.NetworkThread";
    [thread start];
    });
    return thread;
    }
  • (instancetype)init
    {
    self = [super init];
    if (self) {
    // _waitGroup = dispatch_group_create();
    // dispatch_group_enter(_waitGroup);
    [self __initMutex:&_lock];
    }
    return self;
    }

  • (void)main
    {

    @autoreleasepool {
    _runLoop = [NSRunLoop currentRunLoop];
    // dispatch_group_leave(_waitGroup);
    // 激活一个等待该条件的线程
    pthread_cond_signal(&_cond);
    NSLog(@"2222");
    // Add an empty run loop source to prevent runloop from spinning.
    CFRunLoopSourceContext sourceCtx = {
    .version = 0,
    .info = NULL,
    .retain = NULL,
    .release = NULL,
    .copyDescription = NULL,
    .equal = NULL,
    .hash = NULL,
    .schedule = NULL,
    .cancel = NULL,
    .perform = NULL
    };
    CFRunLoopSourceRef source = CFRunLoopSourceCreate(NULL, 0, &sourceCtx);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
    CFRelease(source);

      while ([_runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) {
          
      }
      assert(NO);
    

    }
    }

  • (NSRunLoop *)runLoop;
    {
    // 等待条件(进入休眠,放开mutex锁;被唤醒后,会再次对mutex加锁)
    pthread_cond_wait(&_cond, &_lock);
    NSLog(@"1111");
    return _runLoop;
    }

@EnD

这个是我修改的关于SRRunLoopThread.m 的修复。
通过测试socket 可以正常使用。

@AsteriskZuo
Copy link

FWIW, elevating the thread priority suppresses the priority inversion warning:

diff --git a/Libraries/WebSocket/RCTSRWebSocket.m b/Libraries/WebSocket/RCTSRWebSocket.m
index 925596f8677..a6244fb677e 100644
--- a/Libraries/WebSocket/RCTSRWebSocket.m
+++ b/Libraries/WebSocket/RCTSRWebSocket.m
@@ -1688,6 +1688,7 @@ static NSRunLoop *networkRunLoop = nil;
   dispatch_once(&onceToken, ^{
     networkThread = [_RCTSRRunLoopThread new];
     networkThread.name = @"com.squareup.SocketRocket.NetworkThread";
+    networkThread.qualityOfService = NSQualityOfServiceUserInteractive;
     [networkThread start];
     networkRunLoop = networkThread.runLoop;
   });

I have no idea whether this doesn't negatively affects anything else as I have no clue what it is used for.

That said, it looks like this module has recently been replaced: #36471

Although there are no warnings, as a rule of thumb, it is not appropriate to use the highest priority for both the network thread and the UI thread.

@amgleitman
Copy link

SocketRocket 0.7.0 fixes this here.

@liamjones
Copy link
Contributor

Note that there is a difference between the fix in this thread vs what SocketRocket 0.7.0 does; SocketRocket is using NSQualityOfServiceUserInitiated, the fix in this thread is using NSQualityOfServiceUserInteractive.

@jacquesdev
Copy link

I've seen this alternative PR to fix the issue, facebookincubator/SocketRocket#659, but not sure which is the best solution. I guess that whichever it is, we'd only be able to get it in a future version of react-native? Just for interest's sake, if this projected updated it's dependency from 0.61 (current) to 0.70 or 0.71, would this still be in a react-native patch release, or would we have to wait for 0.73?

@hwangJi-dev
Copy link

hwangJi-dev commented Nov 3, 2023

@cipolleschi
I'm using the latest version 0.72.6 of React-native and SocketRocket 0.6.1

The SocketRocket version dependency specified in React-Core Modules, React-Core is (=0.6.1).

However, when I run the iOS app on Xcode, I get a memory warning message saying 'Hang Risk, Thread running at QOS_CLASS_USER_INTERACTIVE waiting on a lower QoS thread running at QOS_CLASS_DEFAULT. You will encounter a warning that says 'Investigate ways to avoid priority inversions'.
This issue appears to be resolved in SocketRocket version 0.7.0 cc. link
So could you consider updating the dependency version of SocketRocket?

@cipolleschi
Copy link
Contributor

yes, we are considering it. We couldn't do it before due to transitive dependencies that would have make other libraries incompatible.

@vikrambatra08
Copy link

Any plans for fixing this issue with upcoming releases?

@liamjones
Copy link
Contributor

The commit to move SocketRocket to 0.7.0 (which resolves the issue) is already on main: bab9c83 but it doesn't look like it made it into 0.73.0 or 0.73.1 from what I can see in the release tags.

You could request it to be picked to 0.73.2 here: reactwg/react-native-releases#95

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