• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Inist-CNRS / ezs / 17267738980

27 Aug 2025 01:12PM UTC coverage: 95.388% (-0.1%) from 95.519%
17267738980

Pull #462

github

web-flow
Merge 22c6668dc into 56ca7b899
Pull Request #462: feat: 🎸 add [detach]

2220 of 2404 branches covered (92.35%)

Branch coverage included in aggregate %.

34 of 38 new or added lines in 6 files covered. (89.47%)

4 existing lines in 2 files now uncovered.

4584 of 4729 relevant lines covered (96.93%)

80855.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.68
/packages/spawn/src/pool.js
1
import { spawn } from 'child_process';
2
import { satisfies } from 'semver';
3

4
class Pool {
5
    constructor(template) {
6
        this.template = template;
54✔
7
        this.size = Number(this.template.concurrency);
54✔
8
        this.autoFill = this.size > 0;
54✔
9
        this.size = this.autoFill ? this.size : 1;
54!
10
        this.queue = [];
54✔
11
        this.closed = false;
54✔
12
        this.promises = [];
54✔
13
    }
14

15
    fillup() {
16
        if (!this.closed) {
156✔
17
            Array(Number(this.size - this.queue.length))
150✔
18
                .fill(true)
19
                .map(() => this.template.create())
288✔
20
                .forEach((p) => {
21
                    this.queue.push(p);
288✔
22
                });
23
        }
24
    }
25

26
    async acquire() {
27
        if (this.queue.length === 0 && !this.closed) {
114✔
28
            this.fillup();
42✔
29
        }
30
        const promise = this.queue.shift();
114✔
31
        if (promise === undefined) {
114✔
32
            return Promise.reject(new Error('Broken pool ?'));
12✔
33
        }
34
        if (this.autoFill) {
102!
35
            this.fillup();
102✔
36
        }
37

38
        try {
102✔
39
            const resource = await promise;
102✔
40
            const ok = await this.template.validate(resource);
96✔
41
            if (ok) {
96✔
42
                return Promise.resolve(resource);
90✔
43
            }
44
            return Promise.reject(new Error('Invalid command !'));
6✔
45
        } catch (e) {
46
            return Promise.reject(e);
6✔
47
        }
48
    }
49

50
    destroy(resource) {
51
        return this.template.destroy(resource);
256✔
52
    }
53

54
    async close() {
55
        this.closed = true;
78✔
56
        const resources = [];
78✔
57
        while (this.queue.length > 0) {
78✔
58
            resources.push(this.queue.shift());
186✔
59
        }
60
        try {
78✔
61
            const values = await Promise.all(resources);
78✔
62
            await Promise.all(values.map((r) => this.destroy(r)));
162✔
63
            return Promise.resolve(true);
72✔
64
        } catch (e) {
65
            return Promise.resolve(false);
6✔
66
        }
67
    }
68
}
69

70
const config = {};
12✔
71
const handles = {};
12✔
72

73
// see https://github.com/sequelize/sequelize-pool/blob/master/docs/interfaces/FactoryOptions.md
74
const factory = (command, args, opts, conf) => {
12✔
75
    const create = () => new Promise((resolve, reject) => {
288✔
76
        let spawned = false;
288✔
77
        const child = spawn(
288✔
78
            command,
79
            args,
80
            {
81
                ...conf,
82
                stdio: ['pipe', 'pipe', process.stderr],
83
                detached: false,
84
            },
85
        );
86
        child.once('error', (e) => {
288✔
87
            if (!spawned) {
30!
88
                return reject(e);
30✔
89
            }
90
            return true;
×
91
        });
92
        const ready = () => {
288✔
93
            spawned = true;
258✔
94
            resolve(child);
258✔
95
        };
96
        if (satisfies(process.versions.node, '>=14.0.0')) {
288!
97
            child.on('spawn', ready);
288✔
98
        } else {
UNCOV
99
            process.nextTick(ready);
×
100
        }
101
    });
102
    const validate = (resource) => Promise.resolve(!resource.killed);
96✔
103
    const destroy = (resource) => Promise.resolve(resource.kill());
256✔
104

105
    return {
54✔
106
        create,
107
        validate,
108
        destroy,
109
        ...opts,
110
    };
111
};
112

113
const uid = (...args) => args.map((x) => String(x)).join('');
1,236✔
114

115
const startup = (concurrency, command, args, conf) => new Promise((resolve) => {
618✔
116
    const key = uid(command, args);
618✔
117
    if (!handles[key]) {
618✔
118
        handles[key] = new Pool(factory(command, args, { concurrency }, { ...config, ...conf }));
54✔
119
    }
120
    return resolve(handles[key]);
618✔
121
});
122

123
const shutdown = () => Promise.all(Object.keys(handles).map((k) => handles[k].close()));
54✔
124

125
const pool = {
12✔
126
    startup,
127
    shutdown,
128
    config,
129
};
130

131
export default pool;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc