Conversation
All other usages across the class are via `self.`.
Source code locality helps local reasoning.
Without one, the update block would not run on start, resulting in 100% launches being marked as offline. Hat tip https://msolarana.netlify.app/2018/08/04/monitoring-network-changes/
| dispatch_queue_attr_t attrs = dispatch_queue_attr_make_with_qos_class( | ||
| DISPATCH_QUEUE_SERIAL, | ||
| QOS_CLASS_UTILITY, | ||
| DISPATCH_QUEUE_PRIORITY_DEFAULT |
There was a problem hiding this comment.
The docs indicate that the third parameter to dispatch_queue_attr_make_with_qos_class is a relative priority within the QOS class, and can range from 0 to -15. Usually, we'd want to pass 0, unless we specifically know we want to set it to a lower priority than some other value.
As it happens, DISPATCH_QUEUE_PRIORITY_DEFAULT happens to be equal to 0, but it's semantically the wrong thing to be passing here, because this parameter doesn't take a dispatch_queue_priority_t at all; it just wants an int.
I'd recommend replacing this with 0 explicitly. That's what I've seen in most of the Apple sample code that uses this API. (One such example here).
Though… see below; we may be able to drop this call altogether.
| QOS_CLASS_UTILITY, | ||
| DISPATCH_QUEUE_PRIORITY_DEFAULT | ||
| ); | ||
| self.networkMonitorQueue = dispatch_queue_create("com.automattic.tracks.network.monitor", attrs); |
There was a problem hiding this comment.
Apple's docs (and various Apple engineers) recommend using dispatch_queue_create_with_target instead to create a serial queue that will target one of the existing concurrent views, rather than creating a new root queue. Creating a root queue will usually result in a permanent thread dedicated to this queue, which is definitely overkill for this particular use case.
Bonus: if we use the target API, then I don't think we need to create the attrs above at all.
I really wish this were documented better, but it's not. It's all in WWDC videos and Twitter lore from Apple engineers.
| self.networkMonitorQueue = dispatch_queue_create("com.automattic.tracks.network.monitor", attrs); | |
| dispatch_queue_t utilityQueue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0); | |
| self.networkMonitorQueue = dispatch_queue_create_with_target("com.automattic.tracks.network.monitor", DISPATCH_QUEUE_SERIAL, utilityQueue); |
There was a problem hiding this comment.
@bjhomer, I tried this approach but it behaved as before: When the demo app launches, the update handler block is not called.
I pushed that version to a dedicated branch if you want to play with it 2ca8b3b .
In the meantime, I applied your other suggestion and verified it works following the manual script from the PR description.
What do you think of merging this version in, so we can ship the fix in WordPress 19.5, which is scheduled for the coming Monday, and then figure out why the code that Apple recommends doesn't work?
Thanks!
There was a problem hiding this comment.
There was a problem hiding this comment.
@bjhomer 🤦♂️... I had a feeling I missed something, but couldn't put my finger on it.
I incorporated your suggestion and verified it worked, as you said 🎉 Thanks!
Given my track record in this PR, I dismissed your review and asked for a new one. Much appreciated 🙇♂️
|
Thanks for catching this. Sorry I missed it earlier! |
I'm committing this for reference purposes only as it does not work. When the app starts, the update handler block is not called. See discussion in #199.
bjhomer
left a comment
There was a problem hiding this comment.
I commented about how to make my proposed version work, but I'm okay with this version if you'd prefer it.
Co-authored-by: BJ Homer <bjhomer@gmail.com>
Earlier today, @yaelirub reported an unusual spike in events logged with the device offline in WordPress iOS starting from 19.2.
Together with @twstokes, the tracked it to the Tracks update to version 0.11.0 and the new network reachability logic from #186. Tanner noticed that, at launch, the network path was
nil, resulting in this branch of the network properties logging conditional running.I experienced the same behavior when running the TracksDemo app from this repo (microapps FTW!).
The behavior I experienced was that the block meant to receive network path updates was not called when the monitor started, even though that's the expectation set by the documentation.
I did some googling but nobody reported the issue. I stumbled onto this post by @madsolar8582 that also explicitly sets a queue on which to dispatch the update block execution. I tried it out and it did the trick 🎉
To test
On
trunk, put a breakpoint in the update block:Automattic-Tracks-iOS/Sources/Event Logging/TracksService.m
Line 323 in 7fc4afe
Notice that it's not hit on start, but it is if you change you network interface, for example by turning the Wi-Fi on.
Repeat on this branch and notice that the block is called when the demo app starts (fix) and also when the network changes (no regressions).
Alternatively, use
updateDeviceInformationFromReachabilityas the inspection point for the breakpoint. Ontrunkhere: updateDeviceInformationFromReachability. If you do that, be mindful that it gets called as part ofTracksServiceinit, and will haveself.networkPathnilthere because the monitoring hasn't been setup yet.