You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This post is just for future references to explain the decision of creating a blocking context manager for activating a wakepy Mode. For me and anybody else interested.
Background: It was previously the idea to have an API like this
withkeep.running() asm:
ifnotm.success:
# react on failurerun_long_task()
I have written 0.8.0dev docs (the only place I found the info) that the checking the success would be blocking call (waiting until all methods tried). The entering to the keep.running() mode context manager was therefore seen as non-blocking operation.
Now I was reconsidering this again and came into the conclusion that there is no need for a non-blocking mode enter and all wakepy Mode activations should be blocking (see below for some argumentation).
Example 1: Non-blocking checks for mode activation which has a long-running task
Let's look about example code which could use non-blocking mode enter:
defcheck(mode):
# peek if results ready (non-blocking)ifnotmode.results.ready:
return# we know results are ready. Check the resultsifnotmode.is_active():
# Also switch a flag which says not to react again.react_on_activation_failed(mode)
withkeep.running(block=False) asmode:
step_that_takes_10milliseconds()
check(mode) # 1step_that_takes_a_minute()
check(mode) # 2step_that_runs_for_hours()
This kind of code would check the mode switch twice. Probably in the first check (1) the mode results would not be ready. In the second check (2) the results would be ready with high probability. Another similar example could be:
These both are cases where there is some long running task, say, tens of minutes to days. It should not really matter in this case even if wakepy Mode activation would take few seconds. In worst case, wakepy Mode activation could take 10 seconds(?), and task would be only 10 minutes (otherwise no need for wakepy), so wakepy Mode activation would take 1.6% of total time. I would guess that in most cases the mode switch takes max. 1 second, and long task typically would be something like 3 hours, so wakepy Mode activation would consume 0.009% of total time. Really not something to optimize for, and I don't think it is needed. There are most likely much juicier places to optimize any user code (the rest 99% .. 99.99% of the code).
Result: Non-blocking Mode activation not needed here.
Example 2: Non-blocking checks for mode activation which should occur fast
What about Modes that should be entered fast? Such as a Mode that turns off the action of laptop lid close?
In this case that Mode activation must be blocking as you must wait until the mode activation is done before you may close the lid. Therefore, non-blocking activation does make sense only if there is a long running task coming.
Result: Non-blocking Mode activation not needed here.
Example 3: Needing to switch mode multiple times
What if you have many tasks that might run a long time? Would that mean that the seconds would add up and start to take minutes? No. In this scenario user would only enter the Mode once, before starting running the multiple tasks.
Result: Non-blocking Mode activation not needed here.
Example 4: What about tests including wakepy?
If there are tests for libraries or apps having long running tasks, would it mean that wakepy task switching would be slowing down the tests which could activate a mode hundreds of times?
No. There is WAKEPY_FAKE_SUCCESS environment variable possibility for tests, which will run wakepy all the way until IO operation, and fake mode activation success. This should be really fast operation. Of course some of the code is not ran in tests, but those parts are either tested in unit tests of wakepy (or if they're third party calls, like DBus calls, these are tested in the respective 3rd party repositories)
Result: Non-blocking Mode activation not needed here.
Summary
Non-blocking context manager is not needed for ..
.. long tasks, as typical time savings are perhaps 0.009%, or 1.6% "best case" (Example 1)
.. short tasks, as those tasks either do not need wakepy, or if they do, the results should be known instantly and the call should be blocking (Example 2)
.. collection of short tasks, as that is a long task in disguise and should have just one context manager (Example 3)
.. tests including wakepy, as there is WAKEPY_FAKE_SUCCESS env var for making tests run fast (Example 4)
I could not find any good reason for why a non-blocking context manager would really be required.
Workarounds:
If a non-blocking context manager would be required in a very special case, this can be done by running the context manager in separate thread (user code).
Another solution would be to speed up the Mode activation by adding more threads in the actual activation process (would need wakepy update).
The most likely speed booster in any case would be a good method prioritizer, which would check for example the used platform+DE etc. from environment variables and then use the most probable methods for Mode activation first.
The implementation, testing and documentation of use of non-blocking context manager is much more work than is required for a blocking context manager. For the above reasons, I think the 0.8.0 version of wakepy will have a blocking context manager for activating Modes, and without a real use case this will be the case also for the future releases.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
This post is just for future references to explain the decision of creating a blocking context manager for activating a wakepy Mode. For me and anybody else interested.
Background: It was previously the idea to have an API like this
I have written 0.8.0dev docs (the only place I found the info) that the checking the success would be blocking call (waiting until all methods tried). The entering to the
keep.running()
mode context manager was therefore seen as non-blocking operation.Now I was reconsidering this again and came into the conclusion that there is no need for a non-blocking mode enter and all wakepy Mode activations should be blocking (see below for some argumentation).
Example 1: Non-blocking checks for mode activation which has a long-running task
Let's look about example code which could use non-blocking mode enter:
Example 2: Non-blocking checks for mode activation which should occur fast
Example 3: Needing to switch mode multiple times
Example 4: What about tests including wakepy?
Summary
Beta Was this translation helpful? Give feedback.
All reactions