-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
os
needs fix to detect CPUs or fall back to 1
#19022
Comments
imo the sanest output for not being able to detect cpus is EDIT: |
Yeah, I could see us raising an exception but not fabricating data. The error message will mostly be a generic 'operation failed' error, though. The linked issue is about Android. The reason it fails there is because |
I think this needs to be fixed on NPM and not Node, if we can't detect the # of CPUs I'd rather not fabricate it. We should probably add docs. @bnoordhuis is there an open issue? Can't we just read |
No issue. Android is self-serve. |
There are two possible fixes (reading it from |
how about a new api #include <stdio.h>
#include <unistd.h>
int main() {
fprintf(stderr, "# of CPUs: %ld\n", sysconf( _SC_NPROCESSORS_ONLN));
} seem to be fairly portable across UNIX, and does not have the overhead of file system access. |
How do you think |
aix: linux:
ok - so you meant to say at least in Linux, it is all one and the same! thanks. |
If Node throws for I think documenting the "Couldn't detect -> undefined" behavior seems OK. |
I guess the issue is with the overloaded usage of the API - the original and intended usage for obtaining CPU model, speed etc. and the derived usage of obtaining the CPU count via. the length of the resultant array. While the first one if complex and may not have support from all the platforms, second one is well covered, straight-forward and error free. From an end user's point, os.cpus().length being interpreted as the cpu count makes sense, but its value being So I suggest we have another API for cpucount alone that is reliable and deterministic. |
Looking at the linked issue (rvagg/node-worker-farm@0b2349c) the fact that you have to get the length of the object is a bit of a pain. I'd imagine a natural API to look like: const cpus = os.cpus() || 1 Instead of which you have to do: const cpus = (require('os').cpus() || { length: 1 }).length which isn't exactly obvious. Given that getting the number of cpus is probably the largest use-case for this API, I think I'd be +1 on a separate api for it. |
Some update on this? It would be good that cpus().length returns 1 if /proc/stat is not readable. I opened some other related issues, because those libraries don't do a proper check if cpus() is undefined and fetch their length (which causes errors on limited shells): vuejs/vue-cli#2110 |
This comment has been minimized.
This comment has been minimized.
/cc @nodejs/libuv - please review and advise. If you are good with the proposal in |
Why not throw? The problem is literally "we are unable to detect". There is no value for that except "error", which I thought exceptions were for :) Doesn't that make it way more manageable than trying to fit it into a return value or creating a dedicated API "because edge-case"? If some software needs to be able to run on Android (like NPM), it can catch the exception and deal with it the way they think is appropriate. |
there are 2 things that users use this API for:
throwing is great, but it breaks the second usage categories. how do we help them? especially when we look at their intent - get the count to do some simple math in deciding work sharing etc.? what do you mean by If we extend your argument ( |
@gireeshpunathil The edge-case I'm talking about is |
agree that code change is inevitable if this needs to be fixed - either in the user land or in node / libuv. my point is that: when an API is consumed heavily for its secondary use case (derive cpu count), while the API does not fulfill its primary use case (long list of CPUs) in edge-cases, it is worthwhile to implement the secondary use case as a separate API. |
@gireeshpunathil Wait, can the secondary use-case be reliably implemented on the problem cases (Android)? If so, I didn't get that from the earlier communication and I stand corrected. Then a separate API would make a lot more sense to me 👍 If it were to merely fallback to 1 in those cases, I don't see a purpose for its existence though. |
@ronkorving - thanks
agree, it is not evident whether this is feasible or not, and the discussion so far did not converge into a PoC work (unfortunately I don't have a system to build and test). The potential routes for implementation from the discussion are:
It could be possible that one method depends on another internally, but unless someone tests the feasibility we cannot say in either way. |
Having had to recently go through and try to work around this myself on a system on which this was working and broke only after a recent OS update (android, running termux -- very frustrating when you think you might have made changes that broke working code, rather than it being an OS update from a week or two earlier). What about a simple solution? Allow the user to define a CPU COUNT environment variable (name TBD). This, at least, allows an easy workaround - the user can decide if 1 is appropriate, or can invest a little more effort to identify the hardware and provide the CPU count manually? For this specialized "abuse" of the os.cpus() function - to just get a cpu count, it feels like this would be a good compromise? |
Document that `os.cpus()` can return `undefined` if information about cores is not available. This can happen particularly on unsupported platforms like Android. Fixes: nodejs#19022
It seems unlikely that consensus on an API change or addition is going to happen any time soon. #24408 is a documentation fix. |
Documentation fix closed because I believe the call to I suppose we could change the code up to make the error a bit more friendly in this particular case, but we don't have a way to test such a change in our CI infrastructure because we don't have anything that would trigger the error. So we'd have to resort to monkey-patching |
Ah! The relevant code was changed 3 days ago on the master branch! #24264 51cea61 Up until then, Given all this, I'm inclined to close this. We can't guarantee behavior we can't test. Feel free to re-open or comment if closing this seems like an egregiously wrong decision. |
NPM fails when
os.cpus()
returns undefined. Maybeos.cpus()
should output something better with sane fallback default values?Just an idea. Not sure if it's preferable to expect other programs to check for undefined.
The text was updated successfully, but these errors were encountered: