SergioBenitez / version_check

Rust library for checking the installed/running rustc's version.
https://docs.rs/version_check
Apache License 2.0
50 stars 14 forks source link

Avoid getting `Version`/`Channel`/`Date` information more than once. #21

Open alilleybrinker opened 1 year ago

alilleybrinker commented 1 year ago

Right now, subsequent calls to functions like supports_feature result in Channel being read multiple times, which means a Command gets constructed and run. Relatedly, while triple gets you a (Version, Channel, Date), there's not much you can do with those values, as the exposed API will read fresh ones anyway when you ask questions.

Some options for changing this:

1. TLS Cache

Keep the API the same but add some thread-local-storage std::sync::Once values for the Version, Channel, and Date, to cache the result and avoid loading them again.

2. New Rustc Type

Introduce a new Rustc struct that looks like:

use std::sync::Once;

struct Rustc {
    version: Once<Version>,
    date: Once<Date>,
    channel: Once<Channel>,
}

Then expose the currently-free functions on it, and have them lazily store the values they get into the struct, returning them again on subsequent calls rather than re-reading them. This is basically like the first option, but avoids thread-local storage.

This also lets you keep the current API, and just add the Rustc type for people who want to avoid rereading.

3. Add methods on Version, Channel, and Date to query them

Take the current methods that use these values, and turn them into methods on the values, so you use Version::read or equivalent, and then call methods to make queries for features and the like.

alilleybrinker commented 1 year ago

For an example of the re-reading I'm talking about, see the ahash build script: https://github.com/tkaitchuck/aHash/blob/master/build.rs

SergioBenitez commented 1 year ago

Relatedly, while triple gets you a (Version, Channel, Date), there's not much you can do with those values, as the exposed API will read fresh ones anyway when you ask questions.

This isn't true. Any non-static methods you call on these structures don't read any information from the system. They don't need to: these are parsed structures that contain all of the relevant information. The same is true for each individual structure obtained via the struct's read() method.

Add methods on Version, Channel, and Date to query them

They already have methods to query them.

SergioBenitez commented 1 year ago

The one exception is the supports_feature() function, which indeed has no cached equivalent. That's because it's designed for special cases where you want to support a bootstrapped compiler - this requires checking environment variables that don't correspond to any version information.

We could add another structure, say Flags, that stores the information and makes it queryable, though I'm not sure if this is really worth it. I wouldn't be opposed to it, however.

alilleybrinker commented 1 year ago

Thanks for clarifying the API! I think I was tripped up by the inconsistent naming between the free functions on the methods on the structs. That said, something like the Flags idea would be nice!