Skip to content
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

feat: fetch system information #1314

Merged
merged 39 commits into from
May 11, 2022
Merged

Conversation

derezzedex
Copy link
Member

The goal of this PR is to improve ways to debug Iced's built-in backends creation/boot.

For that, it currently:

  • Adds a new Error::ContextCreationFailed in iced_graphics.
  • Adds some logging around context creation in both renderers (iced_glow and iced_wgpu).
  • Adds a new System variant to Action.
  • Adds a new System::QueryInformation action to fetch system and hardware information (gated by the sysinfo feature flag).
  • Exposes a generic system::Information struct containing acquired hardware information.

If there are any other points that could be worth logging or any new fields that we could add to system::Information, please let me know!

@@ -536,8 +543,10 @@ pub fn run_command<Message: 'static + std::fmt::Debug + Send, E: Executor>(
clipboard: &mut Clipboard,
proxy: &mut winit::event_loop::EventLoopProxy<Message>,
window: &winit::window::Window,
graphics_info: &window::GraphicsInformation,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't think of other ways to do this, I'd be happy to receive feedback on this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could pass a closure impl FnOnce() -> window::GraphicsInformation (or the Compositor directly), so we can lazily request the information only for the relevant Command?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 6e16767.

graphics_info: &window::GraphicsInformation,
) -> Option<Information> {
use sysinfo::{ProcessExt, ProcessorExt, System, SystemExt};
let mut system = System::new_all();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The create says it would better to keep System instead of creating it everytime, but then it would need to be passed in a few places, so I decided to do it like this. Any ideas or feedback?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It depends on what "better" means! If it's just a performance optimization, then I believe it should be fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of 5eefa5d, I've decided to maintain this here (this should isolate the crate to the Action itself).
And it seems that refreshing and creating are almost the same.

@derezzedex derezzedex marked this pull request as ready for review April 21, 2022 14:03
pub(crate) fn get_information(
_graphics_info: &window::GraphicsInformation,
) -> Option<Information> {
None
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure about removing the system::Information struct or/and removing the System::QueryInformation enum variant if sysinfo wasn't enabled, so I decided to turn this into an Option.

Any improvements on this would be nice!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should simply conditionally compile the information function here (i.e. making it available only if sysinfo is enabled).

That way, besides removing the unnecessary Option, if a user tries to request system information in their code without the feature enabled, they will get a compiler error.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply conditionally compiling the system::information helper wouldn't work
because the run_command helper matches on every variant of Action and so
would throw the error for anyone not using sysinfo feature.

So, I've gone ahead and completely remove the sysinfo flag in 5eefa5d.
By not storing and delaying the fetching of information until requested (6e16767),
we remove the need of feature flagging.

Reverting this should be as simples as yanking the last commit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gave it a shot in 93bfe2c.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, would it be possible to also gate the iced_native side? That would make it impossible for someone to misuse this.

I've also commited a simple fix to another issue in a447772 (which I was planning on squashing, but didn't for now).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it would be possible since we cannot guarantee the implementation of every shell will support all of the Action variants.

In any case, I have plans to refactor the way Action and Command work to allow defining them outside of iced_native and introduce additional functionality to a shell.

@hecrj hecrj added feature New feature or request compatibility labels Apr 24, 2022
Copy link
Member

@hecrj hecrj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome. Great work! 👍

I left some suggestions here and there. Let me know what you think!


/// Contains informations about the graphics (e.g. graphics adapter, graphics backend).
#[derive(Debug)]
pub struct GraphicsInformation {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just Information or Description? They both seem descriptive enough when prefixing them with compositor.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed in 5be1ac1.

Additionally refactored access to compositor in 984d1f3, thus changing it to compositor::Information instead of window::Information.

@@ -38,6 +38,9 @@ pub trait Compositor: Sized {
height: u32,
);

/// Returns [`GraphicsInformation`] used by this [`Compositor`].
fn get_information(&self) -> GraphicsInformation;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to avoid using getters in Rust. Does just information work?

If we are trying to convey the idea that this may be slow, then maybe we can use a different verb (e.g. request, fetch...).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed in 005e516.

Since retrieving this information is done through a dependency (that uses system calls), I decided to stick with fetch_, although this is done synchronously.

src/error.rs Outdated
GraphicsAdapterNotFound,
/// The application context could not be created.
#[error("the application context could not be created")]
ContextCreationFailed(iced_graphics::Error),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Context is a very ambiguous term and extremely overused. Maybe we can say GraphicsCreationFailed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 18ecec2.

Comment on lines +36 to +41
let available_adapters: Vec<_> = instance
.enumerate_adapters(settings.internal_backend)
.map(|adapter| adapter.get_info())
.collect();
log::info!("Available adapters: {:#?}", available_adapters);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are only collecting these for logging, maybe we can do it conditionally based on log::max_level?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 7a13928.

@@ -536,8 +543,10 @@ pub fn run_command<Message: 'static + std::fmt::Debug + Send, E: Executor>(
clipboard: &mut Clipboard,
proxy: &mut winit::event_loop::EventLoopProxy<Message>,
window: &winit::window::Window,
graphics_info: &window::GraphicsInformation,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could pass a closure impl FnOnce() -> window::GraphicsInformation (or the Compositor directly), so we can lazily request the information only for the relevant Command?

/// Query for available system information.
///
/// Returns `None` if not using the `sysinfo` feature flag.
pub fn information<Message>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we rename it to request_information?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 8643fbe.

graphics_info: &window::GraphicsInformation,
) -> Option<Information> {
use sysinfo::{ProcessExt, ProcessorExt, System, SystemExt};
let mut system = System::new_all();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It depends on what "better" means! If it's just a performance optimization, then I believe it should be fine.

pub(crate) fn get_information(
_graphics_info: &window::GraphicsInformation,
) -> Option<Information> {
None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should simply conditionally compile the information function here (i.e. making it available only if sysinfo is enabled).

That way, besides removing the unnecessary Option, if a user tries to request system information in their code without the feature enabled, they will get a compiler error.

@derezzedex derezzedex requested a review from hecrj April 27, 2022 20:18
@hecrj hecrj added this to the 0.5.0 milestone Apr 30, 2022
Copy link
Member

@hecrj hecrj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

I noticed that the action blocks the main thread for a second or two. It's not a big deal since you shouldn't be calling this often, but it's still a bit jarring to freeze the GUI to users. So I have moved the slow call to a different thread in f1ec0af.

Let me know what you think and we can merge this!

@hecrj hecrj force-pushed the dev/system-information branch 3 times, most recently from 480cd13 to e34f1d0 Compare May 4, 2022 13:19
hecrj and others added 4 commits May 4, 2022 17:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants