add context to external store .get() and .set() options params - #201
Merged
Conversation
…added as options param to store.destroy method too
dead-horse
reviewed
Sep 16, 2020
| } | ||
|
|
||
| const json = await this.store.get(externalKey, opts.maxAge, { ctx, rolling: opts.rolling }); | ||
| const json = await this.store.get(externalKey, opts.maxAge, { state: ctx.state, rolling: opts.rolling }); |
Member
There was a problem hiding this comment.
you can get state from ctx, can you just don't change store.get and add ctx to store.destroy?
Contributor
Author
There was a problem hiding this comment.
Yep, my first version sends ctx. Then I decided to minimize the pollution of the store methods by sending only the state. I can roll it back to use the ctx.
Each request to my node instance can be to a different db. That's why I need ctx.state.dbName in each store method.
Here is a simplified example of my store using ctx:
const TWO_WEEKS = 14 * 24 * 60 * 60 * 1000;
// Ignore the initialisation of MongoClient at this point
const MongoClient = new mongodb.MongoClient(mongoURI, mongoOptions);
export get = async (key, maxAge, { rolling, ctx}) => {
const db = MongoClient.db(ctx.state.dbName);
const collection = await db.collection('sessions');
return await collection.findOne({ _id: key });
};
const set = async (key, sess, maxAge, { changed, rolling, ctx}) => {
const db = MongoClient.db(ctx.state.dbName);
const collection = await db.collection('sessions');
const ttl = new Date((typeof maxAge === 'number' ? maxAge : TWO_WEEKS) + Date.now());
const document = { ...sess, _id: key, ttl };
await collection.findOneAndUpdate({ _id: key }, { $set: document }, { upsert: true });
};
const destroy = async (key, { ctx}) => {
const db = MongoClient.db(ctx.state.dbName);
const collection = await db.collection('sessions');
await collection.findOneAndDelete({ _id: key });
};
dead-horse
reviewed
Sep 21, 2020
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Due to some weird reasons¹ I need access to the ctx.state in the external store get/set methods.
I'm not sure if it's a good idea to pollute the external store with the context.
From the official documentation:
get(key, maxAge, { rolling }): get session object by keyset(key, sess, maxAge, { rolling, changed }): set session object for key, with amaxAge(in ms)my proposal is to send the context (or ctx.state only) to these methods as an option property:
get(key, maxAge, { ctx, rolling }): get session object by keyset(key, sess, maxAge, { ctx, rolling, changed }): set session object for key, with amaxAge(in ms)If this is quite radical and unnecessary and can introduce memory leaks I can upate my pull request to send only the ctx.state:
get(key, maxAge, { state, rolling }): get session object by keyset(key, sess, maxAge, { state, rolling, changed }): set session object for key, with amaxAge(in ms)¹The reason why I need the context state in my external store:
I have a "generic" RESTfull API koa site for a backend.
I run few instances of this backend and all of them are responsible to handle requests for few different domains at any given time. So each instance can process request from one domain/db then the next request is to another domain/db etc..
The code is exactly the same. I use
ctx.request.hostnameas a database name. I execute my "domain name to database name" middleware before koa session and then I need the db name in my external store provider.My external store provider is a mongodb replicaset.
One way to achieve this is to have a central "session" db that is responsible for all sites sessions. In this case I don't need to mess with
koa-session. The name of this special db can be hardcoded in my external store providerBut I prefer to keep each project sessions in the project db.