Comments (13)
The stackoverflow problem is caused by how errors are handled. Currently app::RuntimeError
's fmt::Debug
implementation has a problem, it uses write!(f, "{:?}", self)
, which will call itself once and once again.
Since I'm not sure how you want this error be handled, I couldn't fix this problem.
Actually you are right, I was thinking about this when I found this error. We can force exit the thread by drop
(maybe? I tried it, and it did quite), but the state will be inconsistent. Maybe we really should let user add some "guardian" to task, so when it is forced to quit, one can do some recovery job(fix some inconsistent state?), or None
when no need for that.
I'm also curious about why that Arc::try_unwrap
returns error, since I'm not very familiar with the whole structure of the code.
BTW, this is a good repo, maybe it could change the future how rust people write gui applications. Looking forward to helping(although I'm no expert in gui or client-side application area).
from azul.
I have sent a pull request to fix ArcUnlockError
problem. Now we should decide if we should force to exit(just exit main thread, and let OS do sub-threads collection).
from azul.
Yeah, I know about this, it actually stack overflows, then crashes for some reason. This is a problem that isn't really easy to solve, because the counter is on a background thread and I can't "kill" the background thread - on the other hand I also can't just exit and leave the background thread running.
or kill the thread nicely
That's kind of the problem, this is impossible, due to how threads work on an operating-system level. I can quit the application without cleaning up the threads, but then the problem is that the background thread is still running, so what should I do?
I know about this, added it to the cards here: https://github.com/maps4print/azul/projects/1#card-13479920 - but I am not sure how to actually solve this. As far as I know, you can only kill processes (both on Linux and on Windows), not individual threads.
from azul.
If you want to "kill" a background thread, create a channel, have the main thread hold an Option, and have the background thread hold the receiver. Each loop iteration of the background thread, it trys receiver.try_recv(), and if that fails due to connection dropped, stops the loop, ending the thread. When you want it to stop, simply replace the Some(Sender) with None on the main thread
from azul.
@LordZane Yes, but you have to understand that the framework has no control over the thread. The task is written by the application programmer, I can't "pause" the execution of a thread from azul. Only the person who uses azul (i.e. you) can control what happens inside the thread. So you would have to create the channel / write the loop. And that's already possible, the question is what happens when a thread isn't programmed in that way and the application exits all windows - should the data model stay alive or not?
from azul.
I'm not sure I understand the issue. Once the main thread ends (all window are closed), the OS should cleanup the background threads, no? No manual cleanup should be necessary
from azul.
I think I can explain a little bit about this.
The tasks are defined by users, one thread for each task will be run when it starts. But when main thread is trying to exit, all tasks, which are defined by users, not guaranteed to exit right away. Currently, there's even no information transferred to tasks, they don't know that the main thread is exiting, the main thread is only doing threads joining, waiting for their completions.
So, the main thread actually is not ended unless all tasks are completed, using a join
.
What we need is to decide what should happen once a user tries to exit before tasks' completion.
Actually, I think it is fine to just end main thread without joining, although this may cause problem. This should be a problem for users to solve.
But how am I getting ArcUnlockError
when force exiting?
from azul.
Yeah I'll investigate the ArcUnlockError
tomorrow, that shouldn't happen.
from azul.
Ok, I have already done that. It is because that tasks lifetime is not ended when run_inner
returns. It actually ends when run
is returning. That is to say, when you do that try_unwrap
, it is not dropped.
from azul.
Right, so what I think would be the right decision to solve this:
- In the
AppConfig
I'll make a field if the application should exit if there are still non-main threads running after all windows are closed (viastd::process::exit
) - and if yes, with what exit code. Exiting destroys the entire process, and therefore the OS can clean up the threads immediately. - Panicking threads / tasks currently crash the entire app.
AppConfig
should have another field to set if (and how) azul should recover from crashed / poisoned tasks. - The default value (
None
) should let the tasks running until they finish. This is likely an application error, etc. but it's not the job of the framework to solve that, the application programmer has to solve it gracefully. TheArc<()>
that gets passed into the task can be used to check if the main thread has exited. This means that tasks can run longer than the main thread (and an application can still be "running" even though all windows have been closed). - Update the async demo to demonstrate this new behaviour
I.e. something like this:
struct AppConfig {
// default: None - don't exit, rather let the threads run
// if it's Some(x), then `std::process::exit(x)` - so:
// Some(0) will call exit(0), Some(1) will call exit(1), etc.
should_exit_after_windows_closed: Option<ExitCode>,
}
from azul.
- Maybe better on a per-task basis? Do exit codes matter? Up to you
- Is this necessary? Rust shouldn't crash after all, if there's an error, it should report it as a Result. Again, up to you
from azul.
1. Maybe better on a per-task basis? Do exit codes matter? Up to you 2. Is this necessary? Rust shouldn't crash after all, if there's an error, it should report it as a Result. Again, up to you
Agreed.
One task may be slow and not critical while another may be fast but critical. So we still want to wait until critical one to finish but leaving the not critical ones exit immediately. And I also think there should be a way for user to change how we react on windows when a closing event is received. Like, one should be able to "hold up" windows, and prompt some "waiting till _ to complete" message till waiting for background tasks.
And for the thread panicking stuff, it should just panic the whole application, because it represents an error instead of simple exception. That means, critical bugs that prevent the whole application to continue. For example, OOM. Then we really should not recover from these, or else, result should be returned.
from azul.
Well, these two problems have been fixed now, it doesn't crash anymore, it just closes the window, but the thread is still active. I do think that this would be an acceptable behaviour, because you wouldn't expect the framework to interfere with user code. Maybe there is indeed a task that should run longer than any window is open. So right now, it just closes the window immediately, but doesn't end the process, since the background thread is still running.
I am closing this for now, since the original issue (that the async example crashes / panics) is fixed. Feel free to reopen if you disagree with that choice.
from azul.
Related Issues (20)
- Compilation error HOT 1
- If would like to split out text shaping what is the plan? HOT 3
- Cargo run error, could nto find IOReader in bincode
- couldn't read D:\soft\cargo/lib/azul-dll-0.0.1/target/release/azul.dll HOT 9
- Cannot compile Azul on M1 MacBook Pro due to older WInit dependency HOT 1
- License not updated on official website HOT 2
- Links broken on azul.rs HOT 6
- Build from crates.io command doesn't work HOT 1
- What's the deal with `extern "C"`? HOT 1
- Timers, Threads and Animations guide and after grade abnormal display HOT 1
- Error from link.exe HOT 1
- Support for more programming languages other than python? HOT 2
- [Suggestion] Game example?
- It is not clear from the README whether azul supports Rust & C, Rust & C++ or Rust & C & C++ HOT 2
- [BUG] 404 error for azul.dll file HOT 3
- get rid of four year old xcb dependency HOT 1
- C header fails to parse with clang
- text_layout word_positions_to_inline_text_layout seems to loose words HOT 2
- azul.pyd not working on win7 and win11 HOT 1
- azul didn't create a window HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from azul.