# pull-drain-gently

> Like pull.drain, but respects CPU load

Latest version **1.1.0** (published 2020-06-27) · MIT license · 0 weekly downloads

## Install

```sh
npm install pull-drain-gently
pnpm add pull-drain-gently
yarn add pull-drain-gently
bun add pull-drain-gently
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.1.0 |
| Published | 2020-06-27 |
| First published | 2019-08-20 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 2 |
| Unpacked size | 60.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | staltz.com |
| Maintainers | staltz |
| Keywords | pull-stream, then, thenable, promise, async-await |

## Links

- npm: https://www.npmjs.com/package/pull-drain-gently
- Repository: https://gitlab.com/staltz/pull-drain-gently
- Homepage: https://gitlab.com/staltz/pull-drain-gently#readme
- Issues: https://gitlab.com/staltz/pull-drain-gently/issues
- npm.io page: https://npm.io/package/pull-drain-gently

## Dependencies (2)

- [pull-pause](https://npm.io/package/pull-pause.md) ~0.0.2
- [cpu-percentage](https://npm.io/package/cpu-percentage.md) ~1.0.3

## Alternatives

- [@commercetools/sync-actions](https://npm.io/package/@commercetools/sync-actions.md) — 25.1K weekly downloads
- [cwait](https://npm.io/package/cwait.md) — 21.4K weekly downloads
- [@ledgerhq/hw-app-cosmos](https://npm.io/package/@ledgerhq/hw-app-cosmos.md) — 4.2K weekly downloads
- [@financial-times/o-loading](https://npm.io/package/@financial-times/o-loading.md) — 2.8K weekly downloads
- [fa](https://npm.io/package/fa.md) — 185 weekly downloads

## Recent versions

- 1.1.0 (latest) — 2020-06-27
- 1.0.1 — 2019-08-20
- 1.0.0 — 2019-08-20

## README

# pull-drain-gently

> Like `pull.drain`, but this respects CPU usage, attempting to stay below a prescribed limit

```bash
npm install --save pull-drain-gently
```

## Usage

### Default use

```js
const pull = require('pull-stream');
const drainGently = require('pull-drain-gently');

pull(
  pull.count(1000000),
  drainGently(x => console.log(x), () => console.log('done')),
);
```

### Tweaking the parameters

This pull-stream sink pulls from the source, but once in a while it will check the CPU usage, and if it has gone above the limit known as the `ceiling`, it pauses draining for `wait` milliseconds, and then resumes, in such a way that it should stay close to the limit. In other words, two parameters control the draining:

- `ceiling`: the maximum CPU usage you want this draining sink to consume, approximately, in percentages (`100` is 100%, not `1`)
- `wait`: the waiting period, in milliseconds, to pause draining in order to allow other tasks to use the CPU

The default CPU ceiling is `88%` and the default waiting period for each pause is `144ms` (roughly 9 frames if you have the UI running at 60fps). This means that the longest pause during which no drains will occur is 144ms.

There is also a third less common parameter, which by default is turned off:

- `maxPause`: a limit in milliseconds for how long to pause between draining. For instance, when `maxPause = 5000`, the draining will remain paused for 5 seconds maximum, after that it will d resume draining *regardless* of the current CPU usage. **The default is `Infinity`**.

To configure your own parameters, pass an `opts` object as the first argument, where **both** ceiling and wait must be defined:

```js
const pull = require('pull-stream');
const drainGently = require('pull-drain-gently');

pull(
  pull.count(1000000),
  drainGently(
    {ceiling: 90, wait: 60}, // <--- opts
    x => console.log(x),
    () => console.log('done'),
  ),
);
```

To configure these parameters, consider that:

- The **greater the `ceiling`** is, the closer this sink behaves to stock `pull.drain`, i.e. the *less gently* it drains with regards to CPU load
- The **smaller the `ceiling`** is, the more time it will take to consume the source, i.e. the slower your application will run overall
- The **greater the `wait`**, the more the actual CPU usage fluctuates below and above the `ceiling`, i.e. the more bumpy the ride is for CPU usage and workload throughput
- The **smaller the `wait`**, the more the actual CPU usage accurately meets the `ceiling`, but also the more overhead there is with many short-lived timers for those pauses

The total time for drainage is also important. `pull.drain` is the fastest, having the shortest total time. `drainGently` with a small `wait` might give a total drainage time of approx. 2.5x that of `pull.drain`.

The defaults `ceiling=88`, `wait=144` are a sweet spot, and it can achieve a total drainage time of approx 1.4x that of `pull.drain`. You can run benchmarks yourself by running `cd perf && ./run-all.sh` in this repository.

The chart below shows results for running the benchmark in `perf` on Ubuntu 18.04.3 x86_64, Intel® Core™ i7-7500U CPU @ 2.70GHz × 4, 15,4 GiB RAM, for different values of ceiling (`c`) and wait (`w`). "Unlimited" means `pull.drain`:

![chart with benchmark results](./chart.png)

## License

[MIT](https://tldrlegal.com/license/mit-license)

---
_Source: https://npm.io/package/pull-drain-gently · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
