-
Notifications
You must be signed in to change notification settings - Fork 520
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
[Foundation] Ensure that we do not block when in the background without a background session. #5463
[Foundation] Ensure that we do not block when in the background without a background session. #5463
Conversation
For background info about the fix, please read #5334 |
Build failure 🔥 Build failed 🔥 |
weird, this compiled locally with no issues.. |
Build failure |
// therefore, we do not have to listen to the notifications. | ||
if (string.IsNullOrEmpty (configuration.Identifier)) { | ||
using (var notification = new NSString ("UIApplicationWillResignActiveNotification")) | ||
notificationToken = NSNotificationCenter.DefaultCenter.AddObserver (notification, BackgoundNotificationCb); |
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.
The observer is never removed, which means the BackgroundNotificationOn delegate contained in the observer will keep a permanent reference to the NSUrlSessionHandler instance, and it will never be collected by the garbage collector.
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.
that string constant is already a field/notification inside UIApplication
, WillResignActiveNotification
any reason why you can't use it ?
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.
Yes, we are not compiling the class at a point in time in which we have access to it. Please take a look at the first commit build error in the bots :/
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.
That error looks like it was because it's compiling for watchOS where UIApplication
is not available.
https://developer.apple.com/documentation/uikit/uiapplicationwillresignactivenotification?language=objc does not mention watchOS has this constant.
Using the name manually you're working around that - but it's unlikely the code works one watchOS (the code just make it looks like it should)
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 made that change locally and got the following compilation error:
System.Net.Http/HttpClientHandler.platformnotsupported.cs(129,63): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. HttpClientEx.cs(83,8): warning CS0219: The variable 'webExceptionStatus' is assigned but its value is never used /Users/mandel/Xamarin/xamarin-macios/master/xamarin-macios/src/Foundation/NSUrlSessionHandler.cs(181,87): error CS0117: 'UIApplication' does not contain a definition for 'WillResignActiveNotification' make[3]: *** [../../class/lib/monotouch_watch/reference/System.Net.Http.dll] Error 1
Nevertheless, I'll add the !WATCH to show that it is not done on WatchOS.
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.
the error just means it's not available on watchOS - your code avoid that (at compile time) but it won't change runtime (and you're also exposing a constant string that is not part of the public API on the platform which is, at best, risky).
// therefore, we do not have to listen to the notifications. | ||
if (string.IsNullOrEmpty (configuration.Identifier)) { | ||
using (var notification = new NSString ("UIApplicationWillResignActiveNotification")) | ||
notificationToken = NSNotificationCenter.DefaultCenter.AddObserver (notification, BackgoundNotificationCb); |
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.
that string constant is already a field/notification inside UIApplication
, WillResignActiveNotification
any reason why you can't use it ?
Build success |
Build failure |
Build failure Test results1 tests failed, 0 tests skipped, 80 tests passed.Failed tests
|
void AddNotification () | ||
{ | ||
if (!isBackgroundSession && notificationToken == null) | ||
using (var notification = new NSString ("UIApplicationWillResignActiveNotification")) |
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.
same comments as earlier:
-
why not use
UIApplication.WillResignActiveNotification
instead of your own constant ? Minimally it avoid the memory allocation and any chance of a typo. Also if it ever gets obsoleted we'll not get a compiler warning to update this code. -
why not follow the advice on the field ?
"Use UIApplication.Notifications.ObserveWillResignActive helper method instead."
?
a backgorund session. The mono threadpool gets into an unknown state when the application goes into the background. This fix allows the task that are inflight to be canceled when the app goes to the background allowing the application not to hang and letting the developer retyr the request. If a developer needs to work with the app in the background, he should be using a background session, this fix just ensures that we are left in a known state but does not mean that developers should use this kind of sessions. The MessageHandler class is just used in Mac OS X and does not have the idea of the app going to the background, therefore the fix is not needd in that handler.
7d272ea
to
50c92a2
Compare
@GouriKumari The following steps can be used to reproduce the issue and the fix:
We should check setting the app to the background by:
The testes should see that the requests, when the app goes to the background fail, and that when we get back to the app, it is not stuck and requests continue happening. |
Build failure Test results1 tests failed, 0 tests skipped, 80 tests passed.Failed tests
|
As soon as we have a package I'll post the link here for QA. |
Build success |
You can ignore the VSTS issues :) |
Hello @mandel-macaque @GouriKumari , Following is the status of the pr : - Application output logs:- Screen cast link:- =============================================================== Build info: Application output logs:- Screen cast link:- As discussed with @mandel-macaque on slack, app went to the background and got back, all threads started normally with the logs stating that new ones were created. Hence from QA side it is QA-Approved. Let us know if anything is required from our side. Thanks. |
…andler for thethreadpool. When an application was moved the the background, the thread pool from mono would be left in an unknonw state, making applications to stale (https://xamarin.github.io/bugzilla-archives/58/58633/bug.html#c7). This work was added in dotnet#5463 We now set the default behaviour to skip the workaround to see if the new provided mono works as expected. We do not fully remove the workaround because we need some real world testing. If the new ThreadPool from mono does not work as expected we do provide a property to re-add the workaround. The BypassBackgroundSessionCheck can be set to false to allow users get it back. The following is an example usage of the API: ```csharp // create your own handler instance rather than using the one provided by default. var handler = new NSUrlSessionHandler() { BypassBackgroundSessionCheck = false, // readd the hack }; var httpClient = new HttpClient (handler); // use the handler with the hack ``` This is a partial fix for dotnet#7080
…andler for thethreadpool. (#8296) When an application was moved the the background, the thread pool from mono would be left in an unknonw state, making applications to stale (https://xamarin.github.io/bugzilla-archives/58/58633/bug.html#c7). This work was added in #5463 We now set the default behaviour to skip the workaround to see if the new provided mono works as expected. We do not fully remove the workaround because we need some real world testing. If the new ThreadPool from mono does not work as expected we do provide a property to re-add the workaround. The BypassBackgroundSessionCheck can be set to false to allow users get it back. The following is an example usage of the API: ```csharp // create your own handler instance rather than using the one provided by default. var handler = new NSUrlSessionHandler() { BypassBackgroundSessionCheck = false, // readd the hack }; var httpClient = new HttpClient (handler); // use the handler with the hack ``` This is a partial fix for #7080
The iOS NSUrlSessionHandler needed to use a workaround to ensure that Http requests that were performed by the application did not end up in a stale situation in which the completion would never be reached. This was due to dotnet/macios#5463 This workound will listen to the UIApplication notifications and would cancel all the inflight requests. For reference, this happens here: https://github.com/xamarin/xamarin-macios/blob/main/src/Foundation/NSUrlSessionHandler.cs#L174 As you can see, if we set the property to false, we will get the notification. This is **not longer needed** as mono fixed the runtime issue. The Xamairn.iOS team skips that workaround by default as per this commit: dotnet/macios@b6fbae5#diff-1e7e2b8b4f4fe98a485a36c085a0e9cb94f53fa87a3ff11c7c54682cc3b9d514 This library should not be using the workaround because it will have undesired side effects on applications because they will have cancelation exceptions that are not expected AND the library does not provide an API to reuse the HttpClient instance configured by the client.
The iOS NSUrlSessionHandler needed to use a workaround to ensure that Http requests that were performed by the application did not end up in a stale situation in which the completion would never be reached. This was due to dotnet/macios#5463 This workound will listen to the UIApplication notifications and would cancel all the inflight requests. For reference, this happens here: https://github.com/xamarin/xamarin-macios/blob/main/src/Foundation/NSUrlSessionHandler.cs#L174 As you can see, if we set the property to false, we will get the notification. This is **not longer needed** as mono fixed the runtime issue. The Xamairn.iOS team skips that workaround by default as per this commit: dotnet/macios@b6fbae5#diff-1e7e2b8b4f4fe98a485a36c085a0e9cb94f53fa87a3ff11c7c54682cc3b9d514 This library should not be using the workaround because it will have undesired side effects on applications because they will have cancelation exceptions that are not expected AND the library does not provide an API to reuse the HttpClient instance configured by the client.
The mono threadpool gets into an unknown state when the application goes
into the background. This fix allows the task that are inflight to be
canceled when the app goes to the background allowing the application
not to hang and letting the developer retyr the request.
If a developer needs to work with the app in the background, he should
be using a background session, this fix just ensures that we are left in
a known state but does not mean that developers should use this kind of
sessions.
The MessageHandler class is just used in Mac OS X and does not have the
idea of the app going to the background, therefore the fix is not needed
in that handler.