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

UI stuck at unsubscribe or calling subscribe when connection disconnected #673

Closed
shoaibahmedqureshi opened this issue Jan 25, 2018 · 15 comments
Labels
bug Something isn't working. It's clear that this does need to be fixed.

Comments

@shoaibahmedqureshi
Copy link

I am experiencing a crashing issue using pod version 'Ably', '1.0.10' . I have seen a couple of crashing issue fixes and I am not sure if it's fix is a part of the new release or not and because of this crash UI gets hanged often and does not respond. Below is the stack trace for the crash for further clearance.

Thread says something like below:
KSCrashAblyFork`monitorCachedData(userData=0x000000010db0e54e) at KSCrashCachedData.c:148

Crash back trace.txt

@funkyboy
Copy link
Contributor

@shoaibahmedqureshi on which target is this happening? iOS9, 10, 11?

@shoaibahmedqureshi
Copy link
Author

I currently tested it on ios 11

@funkyboy
Copy link
Contributor

funkyboy commented Jan 25, 2018

@shoaibahmedqureshi Are you by chance adding an observer to NSNotificationCenter in any of your code? If yes, are you removing it in dealloc or (if it's a ViewController) in viewWillDisappear?

@shoaibahmedqureshi
Copy link
Author

I am using NSNotificationCenter on main screen and i am not removing it in viewWillDisappear as if someone subscribe on other screens I want that update to be reflected there.

@shoaibahmedqureshi
Copy link
Author

shoaibahmedqureshi commented Jan 25, 2018

Btw I just added removeObserver statement in my viewWillDisappear method.

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
client.isMapView = false
self.navigationController?.navigationBar.isHidden = false
NotificationCenter.default.removeObserver(self)
}

I am still able to reproduce this issue.

@funkyboy
Copy link
Contributor

@shoaibahmedqureshi It looks like the issue is triggered from here: https://github.com/ably/ably-ios/blob/f87bb50176b89ac8a92318bf4fe03094ea28a6b0/Source/ARTConnection.m#L84 when you (or indirectly the code you wrote) asks for the value of state. According to the crash log, that is performed on a background queue. Correct?
Also, are you accessing the state value on line 17 of AppDelegate.swift?

@shoaibahmedqureshi
Copy link
Author

yes i am performing ably operations on background thread and before every call i try to check the ably connection status and yes crash occurs somewhere around this. no i am not accessing ably in AppDelegate my app delegate looks something like

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    UIApplication.shared.statusBarStyle = .default //.default
    let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
    if statusBar.responds(to:#selector(setter: UIView.backgroundColor)) {
        statusBar.backgroundColor = UIColor.hexStringToUIColor(hex:APP_BLUE_COLOR)
    }
    UIApplication.shared.statusBarStyle = .lightContent

    _ = GMSServices.provideAPIKey("xyz")
    Configuration.currentEnvironment = .production // .development   //
    UILabel.appearance().substituteFontName = APP_DEFAULT_FONT
    UIButton.appearance().substituteFontName = APP_DEFAULT_FONT
    
    UISearchBar.appearance().barTintColor = UIColor.hexStringToUIColor(hex:APP_THEME_COLOR)
    UISearchBar.appearance().tintColor = UIColor.white
    let selectedLang = UserSessionWrapper.getLanguage()
    Bundle.setLanguage(selectedLang)
    
    
    let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
        // Enable or disable features based on authorization.
    }
    application.registerForRemoteNotifications()
    
    ToastManager.shared.tapToDismissEnabled = true
    ToastManager.shared.queueEnabled = true
    Fabric.with([Crashlytics.self])
    return true
}

func applicationWillResignActive(_ application: UIApplication) {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}

func applicationDidEnterBackground(_ application: UIApplication) {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

func applicationWillEnterForeground(_ application: UIApplication) {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

func applicationDidBecomeActive(_ application: UIApplication) {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

func applicationWillTerminate(_ application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    Generic.callAysnc {
        UserSessionWrapper.exitMyApp()
    }
    
}

}

@mattheworiordan mattheworiordan added the bug Something isn't working. It's clear that this does need to be fixed. label Jan 30, 2018
@funkyboy
Copy link
Contributor

@shoaibahmedqureshi Update as per our calls:

  • This is NOT a crash, it's the UI hanging
  • UI hangs after the following happens:
    • Start the app and subscribe to 9-10 channels
    • Go back to the map and see icons (which are displayed according to the messages received)
    • tap refresh on the map, which does the following:
      • unsubscribe from all channels, all at once
      • don't wait for "I am unsubscribed" events
      • subscribe again to the same channels, all at once

Things we explored:

  • removed the KSCrash dependency and stubbed related sentry methods
  • turn on thread sanitizer
  • commented out code drawing icons on the map

Hint

There should be some code like this (of Swift equivalent):

dispatch_async(queue, ^{
    dispatch_sync(queue, ^{
		...
    });
});

that triggers the deadlock. It's still not clear if this is part of Ably SDK or not.

Action: build a simple project that tries to reproduce this behavior.

cc @ricardopereira

@funkyboy funkyboy changed the title Crash occurring at unsubscribe or calling subscribe when connection disconnected UI stuck at unsubscribe or calling subscribe when connection disconnected Jan 30, 2018
@ricardopereira
Copy link
Contributor

@funkyboy So, you suspect it's a deadlock? When it hangs, do you saw any _dispatch_sync_wait that doesn't unlocks?

@funkyboy
Copy link
Contributor

@shoaibahmedqureshi in the meantime, see the question above.

@shoaibahmedqureshi
Copy link
Author

shoaibahmedqureshi commented Jan 31, 2018

@ricardopereira during the debugging process we explored the code and in my application's code most of calls I had were asynchronous except a couple of serial ques I was using before marker drawing to avoid race condition so we commented them out to find out if they are the real culprit but issue was reproducible without them too. I am not sure about calls within ably library though.

@funkyboy
Copy link
Contributor

funkyboy commented Feb 1, 2018

@shoaibahmedqureshi will build a sample project tomorrow, trying to replicate this.
Will post the link here when ready.

@funkyboy
Copy link
Contributor

funkyboy commented Feb 2, 2018

@shoaibahmedqureshi Here is my sample project, but I couldn't manage to make the UI hang. Feel free to fork and tweak.

@shoaibahmedqureshi
Copy link
Author

@funkyboy I will try to tweak and will let u know if i am able to and reproduce this issue.

@funkyboy
Copy link
Contributor

@shoaibahmedqureshi Closing this. Feel free to reopen if this is still an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working. It's clear that this does need to be fixed.
Development

No branches or pull requests

4 participants