Skip to content

Commit

Permalink
Upgrade to latest asyncforge (#11)
Browse files Browse the repository at this point in the history
* Remove the use of enterWith

Signed-off-by: Matteo Collina <[email protected]>

* fixup

Signed-off-by: Matteo Collina <[email protected]>

* fixup

Signed-off-by: Matteo Collina <[email protected]>

* fixup

Signed-off-by: Matteo Collina <[email protected]>

* added store.enterWith()

Signed-off-by: Matteo Collina <[email protected]>

* fixup

Signed-off-by: Matteo Collina <[email protected]>

* updated asyncforge

Signed-off-by: Matteo Collina <[email protected]>

* fixup

Signed-off-by: Matteo Collina <[email protected]>

---------

Signed-off-by: Matteo Collina <[email protected]>
  • Loading branch information
mcollina authored May 21, 2024
1 parent dffba64 commit d0a94e7
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 188 deletions.
66 changes: 11 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,19 @@ npm i fastify fastify-asyncforge
## Usage

```js
// App.js
// app.mjs
import fastify from 'fastify'
import { start } from 'fastify-asyncforge'
import doWork from './do-work.mjs'
import asyncforge, { logger } from 'fastify-asyncforge'

const app = fastify({
logger: true
})
await app.register(asyncforge)

// It's fundamental that `start` is called before any other plugins are registered, otherwise the helpers
// would not work as expected
await start(app)
app.runInAsyncScope(() => {
logger().info('hello')
})

app.decorate('foo', 'bar')
app.decorateRequest('a')
Expand Down Expand Up @@ -54,69 +55,24 @@ export default function doWork () {
}
```

### enterWith

If you need to alter the current asynchronous context, you can use the `enterWith` helper.

```js
import { before, describe, it } from "node:test";
import Fastify from "fastify";
import asyncforge, { app, start } from "fastify-asyncforge";
import assert from "node:assert/strict";

let fastify;

async function build(config) {
const server = await Fastify();

server.register(asyncforge)
server.decorate("config", config);
console.log("config from memo", app().config);

return server;
}

describe("support exiting from a context", () => {
before(async () => {
fastify = await build({ foo: "bar" });
});

it("throws", () => {
assert.throws(app);
});

it("does not throw using enterWith", () => {
fastify.enterWith();
assert.equal(app(), fastify);
});
});
```

## Usage together with other async_hooks tools (e.g. DataDog, OpenTelemetry, etc)
## `.enterWith()`

If you are using `fastify-asyncforge` together with another `async_hooks` based tool,
you __must__ call `start` without adding an intermediate async function.
Alternatively, you'd need to use `.enterWith()`
In case `.runInAsyncScope()` is incovenient, you can use `.enterWith()`

```js
import fastify from 'fastify'
import asyncforge from 'fastify-asyncforge'

const fastify = Fastify()

async function wrap () {
// This is necessary to make it throw
await 1
await asyncforge.start(fastify)
}

await wrap()

// Calling .enterWith() is necessary or `asyncforge.app()` will throw
fastify.enterWith()
asyncforge.app()
```

### Notice

Note that you cannot wrap `.enterWith()` inside an async function, as it will not work.
If you are interested in knowing more, read https://github.com/nodejs/node/issues/53037.

## License
Expand Down
16 changes: 7 additions & 9 deletions example/app.js → example/app.mjs
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
'use strict'

const fastify = require('fastify')
const doWork = require('./do-work')
const { logger, start } = require('../index')
import fastify from 'fastify'
import doWork from './do-work.mjs'
import asyncforge, { logger } from '../index.js'

const app = fastify({
logger: true
})
app.register(require('../index'))

start(app)
await app.register(asyncforge)

logger().info('hello')
app.runInAsyncScope(() => {
logger().info('hello')
})

app.decorate('foo', 'bar')
app.decorateRequest('a')
Expand Down
6 changes: 2 additions & 4 deletions example/do-work.js → example/do-work.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
'use strict'
import { logger, app, request, reply } from '../index.js'

const { logger, app, request, reply } = require('../')

module.exports = function doWork () {
export default function doWork () {
const log = logger()
log.info({
foo: app().foo,
Expand Down
3 changes: 2 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {

declare module "fastify" {
interface FastifyInstance {
enterWith: () => void;
runInAsyncScope<T> (fn: () => T) : T;
enterWith() : void
}
}

Expand Down
54 changes: 29 additions & 25 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,51 @@
'use strict'

const fp = require('fastify-plugin')
const { memo, setAll } = require('asyncforge')
const { memo, create } = require('asyncforge')

const app = memo('fastify.app')
const request = memo('fastify.request')
const reply = memo('fastify.reply')
const logger = memo('fastify.logger')

const fastifyAsyncForge = fp(function (fastify, opts, next) {
fastify.decorate('runInAsyncScope', function (fn) {
const store = create()
return store.run(() => {
app.set(this)
logger.set(this.log)
return fn()
})
})

fastify.decorate('enterWith', function () {
try {
app()
} catch {
setAll({
[app.key]: this,
[logger.key]: this.log
})
}
const store = create()
store.enterWith()
app.set(this)
logger.set(this.log)
})

fastify.addHook('onRequest', async function (req, res) {
setAll({
[app.key]: this,
[request.key]: req,
[reply.key]: res,
[logger.key]: req.log
fastify.addHook('onRequest', function (req, res, next) {
const store = create()

// We use callbacks because we cannot propagate through async/await
store.run(() => {
app.set(this)
request.set(req)
reply.set(res)
logger.set(req.log)
next()
})
})
next()
})

function start (fastify) {
setAll({
[app.key]: fastify,
[logger.key]: fastify.log
create(() => {
app.set(fastify)
logger.set(fastify.log)
next()
})

return fastify.register(fastifyAsyncForge)
}
})

module.exports = fastifyAsyncForge
module.exports.start = start
module.exports.app = app
module.exports.request = request
module.exports.reply = reply
Expand Down
2 changes: 1 addition & 1 deletion index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ const fastifyInstance = fastify();
expectAssignable<FastifyInstance>(fastifyInstance.register(fastifyasyncforge));
expectAssignable<FastifyPluginCallback>(fastifyasyncforge);
expectType<void>(fastifyInstance.enterWith());
expectType<number>(fastifyInstance.runInAsyncScope(() => 42));

// app
expectAssignable<FastifyInstance>(fastifyInstance);
expectAssignable<FastifyInstance>(app());
expectType<void>(app().enterWith());
expectAssignable<FastifyInstance>(app<FastifyInstance<RawServerDefault>>());
expectError<FastifyInstance>(app<string>());
expectError<FastifyInstance>({});
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"tsd": "^0.31.0"
},
"dependencies": {
"asyncforge": "^0.2.0",
"asyncforge": "^0.5.0",
"fastify-plugin": "^4.5.1"
},
"types": "index.d.ts"
Expand Down
17 changes: 3 additions & 14 deletions test/async-hooks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@ test('async_hooks lose context', async (t) => {
const fastify = Fastify()
t.after(() => fastify.close())

async function wrap () {
// This is necessary to make it throw
await 1
await fastifyAsyncForge.start(fastify)
}

await wrap()
await fastify.register(fastifyAsyncForge)

// This is expected to throw due to https://github.com/nodejs/node/issues/53037
p.throws(logger)
Expand Down Expand Up @@ -51,13 +45,8 @@ test('enterWith fixes it', async (t) => {
const fastify = Fastify()
t.after(() => fastify.close())

async function wrap () {
await 1
await fastifyAsyncForge.start(fastify)
}

await wrap()
await fastify.enterWith()
await fastify.register(fastifyAsyncForge)
fastify.enterWith()

p.strictEqual(logger(), fastify.log)
p.strictEqual(app(), fastify)
Expand Down
Loading

0 comments on commit d0a94e7

Please sign in to comment.