I have an application using raylib/raygui this is drawing UI in immediate mode.
for this application I need to do a database call using input retrieved from the UI. This database call is a bit heavy and can take a sec to complete. If I would handle this on the main thread that means the UI would block until that request is done.
With the new Io I’m not sure how I could handle this in the best and most idiomatic way? Should the std.Io be used here, std.Thread or a combination of both?
With Io.async/concurrent I would need to await to ensure it’s completed, as far as I understand, this is a blocking call so I should not do that inside the main loop.
Maybe I could use Io.Group as I read in another post that that should be used for running things in a detached way? But reading the comments it mentions that it’s does not guarentee execution until await is called, so again the same problem.
Or post the request in a Io.Queue and have a seperate worker thread pick it up, this thread could be spawned using std.Thread or have a polling job on Io.Group? But now, I need some mechanism to indicate that the work is done and the results can be shown.
The first thing I want to point out is that blocking the UI thread is sometimes the correct thing to do. Making UI actions async causes UI elements to jump around unpredictably, leading to misclicks and general frustration. It also prevents the user from productively queuing up inputs, making it so that the user must input actions slowly and carefully.
That being said, of course there are sometimes reasons to do things outside the UI thread.
It sounds like you’re not quite sure what behavior you want, so I’m not sure how to advise, but if you’re deciding between threads and std.Io API, I’d encourage you to give the std.Io APIs a try before directly using threads.
Reading your questions again, it sounds like you basically want to poll for completion in your main loop. You can do that with Io.Queue by passing min=0 to get.
In some cases this is certainly true, though if you let it block you also cannot show for example a loading icon to show the user something is happening. in this case the call generally takes between 4-6sec, the user might think the application is stuck or something.
I was mostly searching for what the preferred way would be to handle this case now that there are more solutions to achieve this with the std(Thread/Io). Now that I’m thinking about it, is there any use case left for std.Thread? the std.Io seems quire complete.
This is exactly what I was looking for! I guess I need to read the comments in the code more carefully, I just read the possible blocking part mentioned at the get function
Yes that’s kind of the point. Unless you specifically need threads for some reason, std.Io APIs are a more reusable mechanism. This is a good example of what is meant by “specify intent precisely”. If you specifically need threads, then specify that. But if what you need is only actually “a unit of concurrency” then it’s better to express that.
You’re welcome. Happy hacking, and please feel free to offer any feedback, or ask more questions about std.Io APIs.
I have one small question/feedback, I’m playing with Io.Queue.get
right now. Is it not more idiomatic to have it return a slice instead of a usize? Generally in zig std it’s normal to pass a slice as buffer and than return an updated slice with the correct size right?
would also allow for this syntax: