-
Notifications
You must be signed in to change notification settings - Fork 16
expose flush
on RCTWebSocketModule to close all open websockets synchronously
#14
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
Conversation
…chronously add log statement back
@@ -51,6 +51,16 @@ - (NSArray *)supportedEvents | |||
return @[ @"websocketMessage", @"websocketOpen", @"websocketFailed", @"websocketClosed" ]; | |||
} | |||
|
|||
|
|||
- (void)flush |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function will be called from here: https://github.com/discord/discord/pull/72585
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! This was a tricky problem to solve, and it's cool to see it working 🎉 . Other than a non-blocking naming nit / question, the code looks good to me. I'd also appreciate a review from @lsdimagine , since I'm less familiar with objective C
@@ -24,6 +24,9 @@ NS_ASSUME_NONNULL_BEGIN | |||
|
|||
- (void)sendData:(NSData *)data forSocketID:(nonnull NSNumber *)socketID; | |||
|
|||
// Closes all open websockets on the main thread | |||
- (void)flush; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit / question on naming: does this method empty any buffers or perform any remaining actions in a queue? That's what the "flush" terminology makes me think. If the method does something like that, then the name makes sense. If it doesn't do that, then a name like closeAllSockets
would be clearer to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i updated the implementation + comment to be more in line with the function name (flush)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! The comments are helpful, and this makes more sense to me now
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
…tion for existing view (facebook#51294) Summary: Pull Request resolved: facebook#51294 changelog: [internal] Fix a crash where a node that is supposed to be culled doesn't get visited because culling context is not updated. The differentiator would generate a create instruction for a view that already exists. Stack trace for the crash: ``` * thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT * frame #0: 0x0000000111740874 libsystem_kernel.dylib`__pthread_kill + 8 frame #1: 0x00000001117aa2ec libsystem_pthread.dylib`pthread_kill + 264 frame #2: 0x0000000180171ea8 libsystem_c.dylib`abort + 100 frame #3: 0x00000001802b0144 libc++abi.dylib`abort_message + 128 frame #4: 0x000000018029fe4c libc++abi.dylib`demangling_terminate_handler() + 296 frame #5: 0x000000018006f220 libobjc.A.dylib`_objc_terminate() + 124 frame #6: 0x00000001375d1964 INFRAFramework`meta_terminate() + 5468 frame #7: 0x00000001802af570 libc++abi.dylib`std::__terminate(void (*)()) + 12 frame #8: 0x00000001802b2498 libc++abi.dylib`__cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*) + 32 frame #9: 0x00000001802b2478 libc++abi.dylib`__cxa_throw + 88 frame #10: 0x0000000180093904 libobjc.A.dylib`objc_exception_throw + 384 frame #11: 0x0000000180e6999c Foundation`-[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 268 frame #12: 0x000000031a3bcfc8 XPLAT_6_Framework`-[RCTComponentViewRegistry dequeueComponentViewWithComponentHandle:tag:] + 528 frame #13: 0x000000031a3ccdec XPLAT_6_Framework`RCTPerformMountInstructions(std::__1::vector<facebook::react::ShadowViewMutation, std::__1::allocator<facebook::react::ShadowViewMutation>> const&, RCTComponentViewRegistry*, RCTMountingTransactionObserverCoordinator&, int) + 356 frame #14: 0x000000031a3ccc7c XPLAT_6_Framework`-[RCTMountingManager performTransaction:]::$_1::operator()(facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&) const + 80 frame #15: 0x000000031a3ccc20 XPLAT_6_Framework`decltype(std::declval<-[RCTMountingManager performTransaction:]::$_1&>()(std::declval<facebook::react::MountingTransaction const&>(), std::declval<facebook::react::SurfaceTelemetry const&>())) std::__1::__invoke[abi:ne190102]<-[RCTMountingManager performTransaction:]::$_1&, facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&>(-[RCTMountingManager performTransaction:]::$_1&, facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&) + 40 frame #16: 0x000000031a3ccbc8 XPLAT_6_Framework`void std::__1::__invoke_void_return_wrapper<void, true>::__call[abi:ne190102]<-[RCTMountingManager performTransaction:]::$_1&, facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&>(-[RCTMountingManager performTransaction:]::$_1&, facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&) + 40 frame #17: 0x000000031a3ccb94 XPLAT_6_Framework`std::__1::__function::__alloc_func<-[RCTMountingManager performTransaction:]::$_1, std::__1::allocator<-[RCTMountingManager performTransaction:]::$_1>, void (facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&)>::operator()[abi:ne190102](facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&) + 44 frame #18: 0x000000031a3cba1c XPLAT_6_Framework`std::__1::__function::__func<-[RCTMountingManager performTransaction:]::$_1, std::__1::allocator<-[RCTMountingManager performTransaction:]::$_1>, void (facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&)>::operator()(facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&) + 44 frame #20: 0x000000032f219804 XPLAT_1_Framework`std::__1::function<void (facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&)>::operator()(this=0x000000016d4f0c78, __arg=0x000000016d4f0a10, __arg=0x000000016d4f0978) const at function.h:989:10 frame #21: 0x000000032f219668 XPLAT_1_Framework`facebook::react::TelemetryController::pullTransaction(this=0x00000003f4680f00, willMount=0x000000016d4f0c98, doMount=0x000000016d4f0c78, didMount=0x000000016d4f0c58) const at TelemetryController.cpp:39:3 frame #22: 0x000000031a3c5b28 XPLAT_6_Framework`-[RCTMountingManager performTransaction:] + 544 frame #23: 0x000000031a3c5864 XPLAT_6_Framework`-[RCTMountingManager initiateTransaction:] + 456 frame #24: 0x000000031a3c5240 XPLAT_6_Framework`__42-[RCTMountingManager scheduleTransaction:]_block_invoke + 308 frame #25: 0x0000000131f81b84 BOTTOMFramework`__RCTExecuteOnMainQueue_block_invoke + 40 frame #26: 0x000000018017c788 libdispatch.dylib`_dispatch_call_block_and_release + 24 frame #27: 0x0000000180197278 libdispatch.dylib`_dispatch_client_callout + 12 frame #28: 0x00000001801b2fcc libdispatch.dylib`_dispatch_main_queue_drain.cold.7 + 24 frame #29: 0x000000018018c1c4 libdispatch.dylib`_dispatch_main_queue_drain + 1184 frame #30: 0x000000018018bd14 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 40 frame #31: 0x0000000180427fec CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12 frame #32: 0x00000001804229f8 CoreFoundation`__CFRunLoopRun + 1920 frame #33: 0x0000000180421e3c CoreFoundation`CFRunLoopRunSpecific + 536 frame #34: 0x0000000190f62d00 GraphicsServices`GSEventRunModal + 164 frame #35: 0x0000000185bcec98 UIKitCore`-[UIApplication _run] + 796 frame #36: 0x0000000185bd3064 UIKitCore`UIApplicationMain + 124 frame #37: 0x0000000115fbf0bc PRODUCTFramework`main + 200 frame #38: 0x00000001114293d8 dyld_sim`start_sim + 20 frame #39: 0x0000000111506b4c dyld`start + 6000 ``` Reviewed By: rubennorte Differential Revision: D74654157 fbshipit-source-id: 9181bcd28524c71d0ca4620bd630dc0baa172386
…chronously (#14) * expose `flush` on RCTWebSocketModule to close all open websockets synchronously add log statement back * simplify code * simplify even more * change comment
There was a bit of plumbing to do as there were multiple assertions done along the way to ensure this work is done on the workQueue thread.
I tested this out by adding a sleep of 2 seconds inside closeWithCode block. Seems to work fine.
See: https://www.notion.so/discordapp/RFC-Mobile-Gracefully-closing-the-Gateway-Socket-on-App-Termination-69b44fb46f4e4fedbbca7102e9e2ac29 for more info