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

Add Deno.memoryInfo() #6417

Closed
wants to merge 8 commits into from

Conversation

marcopacini
Copy link
Contributor

Add Deno.freemem() that returns the amount of free memory as a number. Implemented using sys-info::mem_info.
Related to https://github.com/denoland/deno/issues/3802

@CLAassistant
Copy link

CLAassistant commented Jun 21, 2020

CLA assistant check
All committers have signed the CLA.

cli/ops/os.rs Outdated
state.check_unstable("Deno.freemem");
state.check_env()?;
match sys_info::mem_info() {
Ok(info) => Ok(JsonOp::Sync(json!(info.free))),
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this op should be called mem_info instead and return the whole sys_info::MemInfo to JavaScript?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It make sense. I made it return only free memory because in issue https://github.com/denoland/deno/issues/3802 it is related to Node.js os.freemem() function.

Copy link
Contributor

Choose a reason for hiding this comment

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

That could be added later in std's node compat.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, now that memoryInfo() returns all memory info the freemen() function can be something like this:

function freemen(): number {
    return memoryInfo().free;
}

If you think it could be fine I can add it.

assertNotEquals(Deno.freemem(), "");
});

unitTest({ perms: { env: false } }, function freememPerm(): void {
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure about the env permission...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mee to. I just opted for the same permission used by other os functions.

Copy link
Member

@ry ry left a comment

Choose a reason for hiding this comment

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

Nice job at implementing this - it looks correct. Thanks for the work!

I wonder if the allow-env permission is what we want here.

Also I'm curious about why you want this op? What's your use-case?

@marcopacini
Copy link
Contributor Author

marcopacini commented Jun 22, 2020

No use case 😅 but let me explain. I wrote a Prometheus client for Deno (ts-prometheus) but when I started to add default metrics (process stats) I got that they aren't accessible from Deno cli. But I got confused and started to implement a freemem function for os rather then a memoryUsage for process 🤦. When I realised it was too late… I already did it so I open the PR.

OT: I'm going to work on #5732 but I don't think there is an easy way to do it in Rust for every platform.

@ry
Copy link
Member

ry commented Jun 22, 2020

I'm going to work on #5732 but I don't think there is an easy way to do it in Rust for every platform.

That would be a welcomed effort. I think https://docs.rs/sys-info/0.7.0/sys_info/struct.MemInfo.html has everything you need?

You can just modify this PR to expose Deno.memoryInfo() ... but we still have to figure out the permissions.

@caspervonb

This comment has been minimized.

@ry
Copy link
Member

ry commented Jun 22, 2020

@caspervonb Number has 53 bits of integer precision - that's about 9000 terabytes. That should be enough, I think...

@marcopacini
Copy link
Contributor Author

Waiting a decision about permissions I modified Deno.memoryInfo() returning now a MemoryInfo object.

@caspervonb
Copy link
Contributor

@caspervonb Number has 53 bits of integer precision - that's about 9000 terabytes. That should be enough, I think...

Errr.. yeah.... it's a double, was thinking 32bit for some reason 🤔

Copy link
Contributor

@caspervonb caspervonb left a comment

Choose a reason for hiding this comment

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

LGTM; some very minor nits on naming, sorry did not catch that earlier. We should at-least try to avoid snake_case in public APIs and the test case could be a little bit stronger.

export interface MemoryInfo {
total: number;
free: number;
avail: number;
Copy link
Contributor

Choose a reason for hiding this comment

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

available: number;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ops, I forgot it 😊

avail: number;
buffers: number;
cached: number;
swap_total: number;
Copy link
Contributor

Choose a reason for hiding this comment

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

swapTotal : number;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right, I am going to change it. Probably it would be better if the linter could raise an error.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would if the test used it, but seems like we don't lint type member names 🤔

buffers: number;
cached: number;
swap_total: number;
swap_free: number;
Copy link
Contributor

Choose a reason for hiding this comment

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

swapFree: number;

unitTest({ perms: { env: true } }, function freemem(): void {
assertNotEquals(Deno.freemem(), "");
unitTest({ perms: { env: true } }, function memoryInfo(): void {
assertNotEquals(Deno.memoryInfo(), {});
Copy link
Contributor

Choose a reason for hiding this comment

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

const info = Deno.memoryInfo();
assert(info.total);
assert(info.free);
assert(info.avail);

// ... and so on to ensure that the fields are being serialized ;
// I believe the linter will object to `swap_total` and `swap_free` having underscores.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I honestly can't figure out whether it is right check every field. Because memory_info function return an empty object when an error occurs. Otherwise it return a MemoryInfo object and I expect its fields are properly set. Or they can be undefined? I expect Rust code doesn't set fields to undefined but I'm honestly not sure.

Copy link
Contributor

@caspervonb caspervonb Jun 25, 2020

Choose a reason for hiding this comment

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

Asserting n >= 0 should be fine.

In the exceptional case that it returns an error in Rust; an exception should be thrown in the JavaScript runtime as-well (e.g return an op-error).

@bartlomieju bartlomieju added cli related to cli/ dir feat new feature (which has been agreed to/accepted) public API related to "Deno" namespace in JS labels Jun 24, 2020
@bartlomieju bartlomieju added this to the 1.2.0 milestone Jun 24, 2020
@marcopacini marcopacini changed the title Add os.freemem() Add Deno.memoryInfo() Jul 6, 2020
@marcopacini
Copy link
Contributor Author

By trying to implement process.memoryUsage() I noticed a potential conflict in getting memory info related to process and os. I think it could be better to have something like Deno.os.memoryUsage() and Deno.process.memoryUsage() or rather Deno.memoryInfo() could return an object like this:

{
    "os": {
        ...
    },
    "process": {
        ...
    }
}

What do you think?

@bartlomieju bartlomieju modified the milestones: 1.2.0, 1.3.0 Jul 14, 2020
@bartlomieju bartlomieju removed this from the 1.3.0 milestone Aug 11, 2020
@bartlomieju
Copy link
Member

@marcopacini sorry for slow review. Your suggestion with Deno.memoryInfo() returning an object sounds good to me. Please rebase your branch

@bartlomieju
Copy link
Member

Superseded by #7350

@bartlomieju bartlomieju closed this Sep 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cli related to cli/ dir feat new feature (which has been agreed to/accepted) public API related to "Deno" namespace in JS
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants