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

Windows support #42

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open

Windows support #42

wants to merge 1 commit into from

Conversation

mjzk
Copy link

@mjzk mjzk commented Sep 12, 2024

fixs #41

@CLAassistant
Copy link

CLAassistant commented Sep 12, 2024

CLA assistant check
All committers have signed the CLA.

@mjzk mjzk force-pushed the windows_support branch 5 times, most recently from 06fc648 to 6b2df75 Compare September 25, 2024 23:58
@mjzk mjzk marked this pull request as ready for review September 26, 2024 01:13
@mjzk mjzk mentioned this pull request Sep 26, 2024
5 tasks
Comment on lines 15 to 18
# There should be no need to install Rustup or a Rust toolchain explicitly.
# The `ubuntu-22.04` image already includes Rustup:
# <https://github.com/actions/runner-images/blob/ubuntu22/20240401.4/images/ubuntu/Ubuntu2204-Readme.md#rust-tools>
# Running `rustc` or Cargo should automatically install the toolchain specified in `rust-toolchain.toml`.
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Instead of removing the comment, update it to explain the same is true for windows-2022.

    # The `ubuntu-22.04` and `windows-2022` images already include Rustup:
    # - <https://github.com/actions/runner-images/blob/ubuntu22/20240401.4/images/ubuntu/Ubuntu2204-Readme.md#rust-tools>
    # - <https://github.com/actions/runner-images/blob/ubuntu22/20240401.4/images/windows/Windows2022-Readme.md#rust-tools>

Copy link
Author

Choose a reason for hiding this comment

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

OK. My personal think for the removal here is: These comments are of little significance. ubuntu-latest is not ubuntu-22.04 mentioned here but Ubuntu 24.04. It doesn't make much sense to let developers maintain these changes.

But, I can also accept that if you, as a committer, think it is necessary to keep. So I will modify it according to your suggestion.

Comment on lines 27 to 28
shell: bash
run: bash scripts/ci/clippy.bash --deny warnings
Copy link
Contributor

Choose a reason for hiding this comment

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

polish: Specifying Bash as the interpreter explicitly should not be necessary.

This step will only run on Linux.
It has worked on Linux until now.

I assume the addition of bash is an oversight.

Suggested change
shell: bash
run: bash scripts/ci/clippy.bash --deny warnings
run: scripts/ci/clippy.bash --deny warnings

Copy link
Author

Choose a reason for hiding this comment

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

OK. The addition of bash is intentional. The two run command diff here is: the original requires the script scripts/ci/clippy.bash in the executable mode. This first has security concerns. But most problem here is, if you check out the script in unsupport OSes and FSes like in Windows, the executable mode will be lost. Then, although you want to execute it in WSL like things. It does not work.

But, I can also accept that if you, as a committer, think you want to use the original command. So I will modify it according to your suggestion.

Cargo.toml Outdated
unsafe_code = 'forbid'
unsafe_code = 'deny'
Copy link
Contributor

Choose a reason for hiding this comment

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

issue: I am opposed to the use of unsafe in this workspace.

Try using winsafe.
winsafe does not have a wrapper for GetProcessMemoryInfo, but you could fork it and even submit a pull request upstream.

Also, it makes little sense to set a lint like unsafe_code to deny.
Unsafe Rust is already opt-in via the unsafe keyword.

Copy link
Author

Choose a reason for hiding this comment

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

@weekday-grandine-io Basically, I do not agree with you on this point.

  1. The sense of deny is to make developer have the chance to opt-out forced lint errors. Here, the result of the behavior that I override that unsafe lint error is controllable and has minimal impact. To forbid unsafe in a large Rust engineering, like Grandine, is just a cover-up in the current situation where we heavily depends on a large number of unsafe libraries.

  2. Although firing a pull request upstream is possible, it is time-consuming, and no guarantee of upstream willing to accept new additions or modifications. I think, that's why we have so many forks in our grandinetech org.

Although I can not agree with you on this point, I can also accept that if you, as a committer, think you just want to use unsafe_code = 'forbid'. But I suggest to reconsidering the fixing way.

There are three kinds of actions now:

  1. keep this change in PR and nothing need to be done.
  2. firstly to fork a project in our grandinetech org, to quick apply update in current PR. Then, make Grandine depends on it and go on...
  3. firstly to fork a project anywhere, to submit an PR upstream. Then, to wait it accepted and make Grandine depends on it after that and go on...

@weekday-grandine-io @sauliusgrigaitis What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

So in the core team, we think that unsafe code is really not desired in Grandine codebase (dependencies is another story). So in order to ensure this philosophy we use unsafe_code = 'forbid'. For sure it's not very convenient whenever a tricky situation comes, but we try to be creative to workaround particular cases so we can still proceed using unsafe_code = 'forbid'.

Copy link
Author

@mjzk mjzk Oct 12, 2024

Choose a reason for hiding this comment

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

@sauliusgrigaitis OK.

I understand our decision although I think it is not very meaningful now. For example, our bad stackoverflow in the debug mod currently. The philosophy of deny, in fact, also forbids the unsafe by default. There is no unintentional unsafe. But again, I respect the core team's decision.

I will follow the above action#3 which was suggested by @weekday-grandine-io , although you didn't suggest which is better in 2 and 3.

Apparently this causes an issue that this PR is being locked by upstream. I will research and contact upstream as soon as possible to resolve this issue. However, there may not be a clear timeline.

Cargo.toml Outdated
Comment on lines 500 to 505
windows = { version = "0.58", features = [
"Win32_Foundation",
"Win32_System_ProcessStatus",
"Win32_System_Threading",
"Win32_System_SystemInformation",
] }
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: We have a convention of using literal strings in TOML files whenever possible.

Also, we usually order features alphabeticaly and do not wrap them over multiple lines.

Suggested change
windows = { version = "0.58", features = [
"Win32_Foundation",
"Win32_System_ProcessStatus",
"Win32_System_Threading",
"Win32_System_SystemInformation",
] }
windows = { version = '0.58', features = [
'Win32_Foundation',
'Win32_System_ProcessStatus',
'Win32_System_SystemInformation',
'Win32_System_Threading',
] }

or

Suggested change
windows = { version = "0.58", features = [
"Win32_Foundation",
"Win32_System_ProcessStatus",
"Win32_System_Threading",
"Win32_System_SystemInformation",
] }
windows = { version = '0.58', features = ['Win32_Foundation', 'Win32_System_ProcessStatus', 'Win32_System_SystemInformation', 'Win32_System_Threading'] }

Copy link
Author

Choose a reason for hiding this comment

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

accepted.

Comment on lines -429 to +432
jemalloc_ctl::epoch::advance().map_err(Error::msg)?;
jemalloc_ctl::epoch::advance().map_err(anyhow::Error::msg)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: Import types at the top of the file.

#[cfg(target_os = "windows")]
use ::{anyhow::Error, bytesize::ByteSize, jemalloc_ctl::Result as JemallocResult};

Copy link
Author

Choose a reason for hiding this comment

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

This import is just used for not(target_os = "windows"). To prompt it to the top in import will cause additional verbose imports.

But, I can also accept that if you, as a committer, think you want to use this more verbose imports.

.is_ok()
} {
memory_process_bytes = mem_counters.WorkingSetSize as _;
trace!("Memory usage: {} bytes", memory_process_bytes);
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: Most error and log messages in the codebase start in lowercase.

Copy link
Author

Choose a reason for hiding this comment

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

accepted.


#[inline(always)]
#[cfg(target_os = "windows")]
fn filetime_to_seconds(ft: &FILETIME) -> u64 {
Copy link
Contributor

Choose a reason for hiding this comment

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

polish: It would be more idiomatic to pass FILETIME as an owned value.

FILETIME is a small struct that implements Copy.

Suggested change
fn filetime_to_seconds(ft: &FILETIME) -> u64 {
fn filetime_to_seconds(ft: FILETIME) -> u64 {

Copy link
Author

@mjzk mjzk Nov 4, 2024

Choose a reason for hiding this comment

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

accepted.

(But passing by ref/pointer indeed follows the FFI convention in the Rust community.)

Comment on lines 200 to 123
fn filetime_to_seconds(ft: &FILETIME) -> u64 {
let total_seconds = ((ft.dwHighDateTime as u64) << 32 | ft.dwLowDateTime as u64) / 10_000_000;
total_seconds
}
Copy link
Contributor

Choose a reason for hiding this comment

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

thought: It would be more idiomatic to return Duration, but that's probably out of scope.

Representing the number of seconds with u64 limits precision to 1 second, but that seems to be required by the Client Stats Proposal.

Copy link
Author

@mjzk mjzk Nov 4, 2024

Choose a reason for hiding this comment

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

It is interesting to see that we have a specification for client stats. This method is indeed a quick method to imitate the original Linux side logic. We can change it in the future if necessary.

#[inline(always)]
#[cfg(target_os = "windows")]
fn filetime_to_seconds(ft: &FILETIME) -> u64 {
let total_seconds = ((ft.dwHighDateTime as u64) << 32 | ft.dwLowDateTime as u64) / 10_000_000;
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Document the magic number somehow.

Consider extracting a constant with a self-documenting name.
Consider linking to the documentation of FILETIME.

Copy link
Author

Choose a reason for hiding this comment

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

accepted.

#[inline(always)]
#[cfg(target_os = "windows")]
fn filetime_to_seconds(ft: &FILETIME) -> u64 {
let total_seconds = ((ft.dwHighDateTime as u64) << 32 | ft.dwLowDateTime as u64) / 10_000_000;
Copy link
Contributor

Choose a reason for hiding this comment

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

note: FILETIME is a kind of timestamp (with an unusual epoch), but GetSystemTimes uses it to represent a duration.

Copy link
Author

Choose a reason for hiding this comment

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

ok.

@mjzk
Copy link
Author

mjzk commented Oct 9, 2024

@weekday-grandine-io thanks for the detailed review. I will react according to my understanding. Although I don't think some of your opinions are necessarily valid, I will give priority to your suggestions.

@mjzk mjzk force-pushed the windows_support branch 2 times, most recently from f219b9b to 4b987ff Compare November 6, 2024 06:55
@mjzk
Copy link
Author

mjzk commented Nov 6, 2024

@sauliusgrigaitis @weekday-grandine-io

For syncing PR to develop branch easier, I do a squash on all commits. And finally CI passed again.

After contacting with upstream, the relevant Windows stats successfully rely on winsafe. This also greatly simplifies the implementation of the metric_sys mod.

Other changes are also made according to the review comments even with some of the changes which I not fully agree with.

If you need any other changes, please let me know and I will try to complete them even after the end of EPF cohort 5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants