soyuka / pidusage

Cross-platform process cpu % and memory usage of a PID
MIT License
512 stars 55 forks source link

`pidusage` doesn't resolve if `pids` array gets modified meanwhile `updateCpu()` gets called #174

Open piranna opened 10 months ago

piranna commented 10 months ago

API Platform version(s) affected:

Probably all, detected while using Ubuntu 23.10

Description

pids array argument is checked not being zero length at https://github.com/soyuka/pidusage/blob/61480f745a3f4dd780118b6aabf00bc1f58d5d87/lib/stats.js#L71-L73, but it's passed and used as reference in all the code, so when calling async function updateCpu() at https://github.com/soyuka/pidusage/blob/61480f745a3f4dd780118b6aabf00bc1f58d5d87/lib/procfile.js#L125, it can be possible that the array gets modified in application code (for example, due to a race condition), so when calling its callback, pids can be a zero length array without getting noticed. This has the effect that fns object will be empty instead of being filled at https://github.com/soyuka/pidusage/blob/61480f745a3f4dd780118b6aabf00bc1f58d5d87/lib/procfile.js#L131-L135, and later when calling to parallel() helper, it will never call to the each() function instead of doing it at https://github.com/soyuka/pidusage/blob/61480f745a3f4dd780118b6aabf00bc1f58d5d87/lib/helpers/parallel.js#L30-L34, and the done() callback will never be called back.

Possible Solution

There are several, not incompatible alternatives:

Personally I would implement at least 2 and 3 for safety, and if we want to get procfile errors on the benefict of having an inmutable input data, also number 1, maybe returning a structure similar to the one returned by Promise.allSettled() that combines both results and errors at the same time.

soyuka commented 10 months ago

would love a pr if you're up to it!

piranna commented 10 months ago

Just to fic this, or a full redactor? There are some needed updates, but others like using Promise.allSettled() would be backward incompatible with older versions of Node.js... but for maintained ones It would be totally safe.

piranna commented 10 months ago

In fact, i'm thinking the best option would be to return an empty object or array if it's zero length, also when provided like this, so i would remové the throwed exceptuon