The worker pool and the default workspaceConcurrency took the CPU count from os.availableParallelism(), which counts the CPUs in the process's affinity mask. In a container with a cgroup CPU quota smaller than that mask, such as a Kubernetes pod with a 4-CPU limit on a 233-CPU node, pnpm 11 created 232 workers per install, and four concurrent installs exhausted a 16 GiB memory limit while the workers were still loading. Node's libuv does try to apply the quota, but its cgroup v1 parser looks for ":cpu," and keeps "cpuacct:" in the path it builds, so it never finds the quota file there, and both it and Rust's standard library give up when the cgroup path from /proc/self/cgroup is not mounted under /sys/fs/cgroup, as happens with a host cgroup namespace and a bind-mounted controller. A new package, `@pnpm/os.available-parallelism`, reads the quota itself: the smallest limit/period walking from the process's cgroup up to the hierarchy root, for cgroup v2 (cpu.max) and v1 (cpu.cfs_quota_us and cpu.cfs_period_us), rounded down and floored at 1 like Rust's std::thread::available_parallelism, which pnpm 12 already uses. The cgroup directory is located through /proc/self/mountinfo, which says which cgroup each mount shows, so a container that sees only its own cgroup bind-mounted at /sys/fs/cgroup is read correctly; the standard mount points are the fallback. The worker pool and the config reader's workspace-concurrency default both use it, so the two stay in step. pnpm 12 is unaffected: every Rust pool is sized with std::thread::available_parallelism, which honours the quota. Closes pnpm/pnpm#17382
124 lines
3.2 KiB
Markdown
124 lines
3.2 KiB
Markdown
---
|
|
id: recursive
|
|
title: pnpm -r, --recursive
|
|
---
|
|
|
|
Aliases: `m`, `multi`, `recursive`, `<command> -r`
|
|
|
|
Runs a command in every project of a workspace, when used with the following commands:
|
|
|
|
* `install`
|
|
* `list`
|
|
* `outdated`
|
|
* `publish`
|
|
* `pack`
|
|
* `rebuild`
|
|
* `remove`
|
|
* `unlink`
|
|
* `update`
|
|
* `why`
|
|
|
|
Runs a command in every project of a workspace, excluding the root project,
|
|
when used with the following commands:
|
|
|
|
* `exec`
|
|
* `run`
|
|
* `test`
|
|
* `add`
|
|
|
|
If you want the root project be included even when running scripts, set the [includeWorkspaceRoot] setting to `true`.
|
|
|
|
Usage example:
|
|
|
|
```sh
|
|
pnpm -r publish
|
|
```
|
|
|
|
By default, recursive `run`, `exec`, and `test` execute projects in
|
|
topological order: dependencies run before their dependents. Use `--no-sort`
|
|
to disable graph ordering, or `--parallel` to start tasks without waiting for
|
|
dependencies.
|
|
|
|
## Options
|
|
|
|
### --link-workspace-packages
|
|
|
|
* Default: **false**
|
|
* Type: **true, false, deep**
|
|
|
|
Link locally available packages in workspaces of a monorepo into `node_modules`
|
|
instead of re-downloading them from the registry. This emulates functionality
|
|
similar to `yarn workspaces`.
|
|
|
|
When this is set to deep, local packages can also be linked to subdependencies.
|
|
|
|
Be advised that it is encouraged instead to use [`pnpm-workspace.yaml`] for this setting, to
|
|
enforce the same behaviour in all environments. This option exists solely so you
|
|
may override that if necessary.
|
|
|
|
[`pnpm-workspace.yaml`]: ../workspaces.md#linkworkspacepackages
|
|
|
|
### --workspace-concurrency
|
|
|
|
* Default: **the smaller of 4 and the number of available CPU cores**
|
|
* Type: **Number**
|
|
|
|
Set the maximum number of tasks to run simultaneously. For unlimited concurrency
|
|
use `Infinity`.
|
|
|
|
In a container with a CPU quota, such as a Kubernetes CPU limit, the quota is the
|
|
number of available CPU cores when it is smaller than the number of CPUs the
|
|
container may run on. A fractional quota is rounded down, to at least 1.
|
|
|
|
You can set the `workspace-concurrency` as `<= 0` and it will use the number of available CPU cores as: `max(1, (number of available CPU cores) - abs(workspace-concurrency))`
|
|
|
|
### --[no-]bail
|
|
|
|
* Default: **true**
|
|
* Type: **Boolean**
|
|
|
|
If true, stops when a task throws an error.
|
|
|
|
This config does not affect the exit code.
|
|
Even if `--no-bail` is used, all tasks will finish but if any of the tasks fail,
|
|
the command will exit with a non-zero code.
|
|
|
|
Example (run tests in every package, continue if tests fail in one of them):
|
|
```sh
|
|
pnpm -r --no-bail test
|
|
```
|
|
|
|
### --[no-]sort
|
|
|
|
* Default: **true**
|
|
* Type: **Boolean**
|
|
|
|
When `true`, commands follow the workspace dependency graph. Recursive `run`
|
|
also applies relationships from the [`tasks` setting]. Pass `--no-sort` to
|
|
remove graph ordering. This also makes `tasks`, `--reverse`, and `--resume-from`
|
|
inapplicable.
|
|
|
|
Example:
|
|
```sh
|
|
pnpm -r --no-sort test
|
|
```
|
|
|
|
### --reverse
|
|
|
|
* Default: **false**
|
|
* Type: **boolean**
|
|
|
|
When `true`, dependency edges are reversed. For recursive `run`, this reverses
|
|
the resolved task graph, including relationships declared with `dependsOn`.
|
|
|
|
```sh
|
|
pnpm -r --reverse run clean
|
|
```
|
|
|
|
### --filter <package_selector\>
|
|
|
|
[Read more about filtering.](../filtering.md)
|
|
|
|
[includeWorkspaceRoot]: ../workspaces.md#includeworkspaceroot
|
|
[`tasks` setting]: ../workspace-task-orchestration.md
|