-
Notifications
You must be signed in to change notification settings - Fork 599
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
Make gears.object:emit_signal
fail proof (Fix #3667)
#3669
base: master
Are you sure you want to change the base?
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3669 +/- ##
=======================================
Coverage 90.65% 90.65%
=======================================
Files 854 854
Lines 54774 54788 +14
=======================================
+ Hits 49653 49666 +13
- Misses 5121 5122 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
I think this is already done. The CAPI wraps function calls in pcall via |
The premise for this is (from #3667 (comment))
But it's not correct that only a change in the library could fix this. The user can wrap "the callback itself" in a And I really don't think this should be done by Awesome, especially when it brings something heavy like env LUA=lua5.1 RUNS=10000000 bash run.sh
"print('Hello')"
real 0m3.451s
user 0m3.423s
sys 0m0.007s
"pcall(print, 'Hello')"
real 0m4.521s
user 0m4.501s
sys 0m0.007s
"protected_call(print, 'Hello')"
real 0m17.791s
user 0m17.697s
sys 0m0.011s For the internal stuff, we have tests (and plenty users running the system) to make sure we don't panic. For user-provided callbacks, like the above, the user can wrap them (only) when they need to. But it gives the user the choice between a performance penalty or potential panics. |
gears.object:emit_signal
fail proof (Fix #3667)
@Aire-One What's your take on this? Should we close this PR? Or should we make a new variant of emit signal with the extra pcalls? There are definitively some places where an error in a signal handler can cause a transaction state to be messed up. However should we just wrap those emit_signal in a pcall rather than have a new method? |
Continuing despite failure can mess things up just as much, and the messed up transaction from the swallowed error could silently run along and fail somewhere else, making debugging much harder. And since it would be the user's callback that panics, they can wrap it themselves, if that is acceptable for their use case. |
i believe it's smth what should be rather better-explained in documentation, not fixed in code |
No, it wouldn't solve the initial issue.
Yeah, I understand your concern. I personally would rather have this performance drop than a silent breakage. As pointed out earlier, we already do the same at the C level with And as you stated, this performance cost is the worst with Lua 5.1 because of the extra business to get around
I disagree with this. Just as the initial issue shown it: there is no panic. It was even worse, since the supposedly one-time timer was called indefinitely.
I guess it's ok-ish, but not idiot-proof, even for us, we could introduce a badly written signal callback that silently breaks something. (*) The fact that the C API already does it for years consolidate my idea we have to do it in Lua as well. |
Right now, when we do this, we don't swallow the errors, the red popup with stacktrace is still shown, we just make sure the cleanup code isn't skipped.
The problem is that it causes a lot of problems. Things like dbus messages should have a reply or the client can get locked. Database transaction have similar problem, where things pending GC because they were not properly finished can affect the new transactions. You can in theory exhaust file descriptors if during an animation. It can also cause memory leaks: local global_cache = {}
client.connect_signal("unmanage", function(c)
module.emit_signal("request::something", "context", {client=c})
global_cache[c] = nil
end) So there are cases where you do want such pcall, it's not universally bad. As for if we should do it everywhere or not, I don't have a super strong opinion. |
No, it does not. And the linked issue even exhibits the "fail somewhere else" component: The
That can be fixed easily: - module.emit_signal("request::something", "context", {client=c})
+ gears.protected_call(module.emit_signal, module, "request::something", "context", {client=c}) The same can be done within the D-Bus messaging or any database query code.
AwesomeWM doesn't crash there, because If the order of these two blocks was reversed, ensuring that the Lines 207 to 216 in b16f628
(different system than the previous benchmarks)
I'm not talking about performance "issues", but more like a "nuisance". Adding a bunch of Additionally, the bigger picture in this context is the fact that we do not have anything to track performance in the long run. Therefore, when changes like this come months or even years apart, they would be considered and decided in isolation. But even though when each change is justifiable in itself, the results will add up, unnoticed. That can either be remedied by occasionally doing performance optimizations (except I'm not aware of that every being done in recent times, or any profiling in the code base that the optimization could be based on) or by making sure the change is only done where absolutely necessary in the first place (which I'm arguing to do here). |
I guess we need to do something similar in the CAPI, but I'm not sure how 🤷