1 | var Fiber = require('../fibers');
|
2 | /** Helpers for Fiber management. */
|
3 | var FiberManager;
|
4 | (function (FiberManager) {
|
5 | /** Returns true if the current execution context is within a fiber. */
|
6 | function isExecutingInFiber() {
|
7 | return !!Fiber.current;
|
8 | }
|
9 | FiberManager.isExecutingInFiber = isExecutingInFiber;
|
10 | /** Creates and returns a new fiber in which an arbitrary function may be executed. */
|
11 | function create() {
|
12 | return Fiber(runInFiber);
|
13 | }
|
14 | FiberManager.create = create;
|
15 | })(FiberManager || (FiberManager = {}));
|
16 | /**
|
17 | * The runInFiber() function provides the prolog/epilog wrapper code for running a function inside
|
18 | * a fiber. The runInFiber() function accepts a RunContext instance, and calls the wrapped function
|
19 | * specified there. The final return/throw value of the wrapped function is used to notify the
|
20 | * promise resolver and/or callback specified in the RunContext. This function must take all its
|
21 | * information in a single argument because it is called via Fiber#run(), which accepts one argument.
|
22 | * NB: Since try/catch/finally prevents V8 optimisations, the function is split into several parts.
|
23 | */
|
24 | function runInFiber(runCtx) {
|
25 | try {
|
26 | tryBlock(runCtx);
|
27 | }
|
28 | catch (err) {
|
29 | catchBlock(runCtx, err);
|
30 | }
|
31 | finally {
|
32 | finallyBlock(runCtx);
|
33 | }
|
34 | }
|
35 | function tryBlock(runCtx) {
|
36 | // Maintain an accurate count of currently active fibers, for pool management.
|
37 | adjustFiberCount(+1);
|
38 | // Call the wrapped function. It may be suspended several times (at await and/or yield calls).
|
39 | var result = runCtx.wrapped.apply(runCtx.thisArg, runCtx.argsAsArray);
|
40 | // The wrapped function returned normally. Notify any waiters.
|
41 | if (runCtx.callback)
|
42 | runCtx.callback(null, result);
|
43 | if (runCtx.resolver)
|
44 | runCtx.resolver.resolve(result);
|
45 | }
|
46 | function catchBlock(runCtx, err) {
|
47 | // The wrapped function threw an exception. Notify any waiters.
|
48 | if (runCtx.callback)
|
49 | runCtx.callback(err);
|
50 | if (runCtx.resolver)
|
51 | runCtx.resolver.reject(err);
|
52 | }
|
53 | function finallyBlock(runCtx) {
|
54 | // Maintain an accurate count of currently active fibers, for pool management.
|
55 | adjustFiberCount(-1);
|
56 | // Execute the done() callback, if provided.
|
57 | if (runCtx.done)
|
58 | runCtx.done();
|
59 | }
|
60 | /**
|
61 | * The following functionality prevents memory leaks in node-fibers by actively managing Fiber.poolSize.
|
62 | * For more information, see https://github.com/laverdet/node-fibers/issues/169.
|
63 | */
|
64 | function adjustFiberCount(delta) {
|
65 | activeFiberCount += delta;
|
66 | if (activeFiberCount >= fiberPoolSize) {
|
67 | fiberPoolSize += 100;
|
68 | Fiber.poolSize = fiberPoolSize;
|
69 | }
|
70 | }
|
71 | var fiberPoolSize = Fiber.poolSize;
|
72 | var activeFiberCount = 0;
|
73 | module.exports = FiberManager;
|
74 | //# sourceMappingURL=fiberManager.js.map |
\ | No newline at end of file |