Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Use LRUCache for extendSessionOnUse #8683

Open
wants to merge 12 commits into
base: alpha
Choose a base branch
from
2 changes: 2 additions & 0 deletions spec/Auth.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ describe('Auth', () => {
updatedAt: updatedAt.toISOString(),
}
);
Parse.Server.cacheController.clear();
await new Promise(resolve => setTimeout(resolve, 1000));
await session.fetch();
await new Promise(resolve => setTimeout(resolve, 1000));
await session.fetch();
Expand Down
70 changes: 38 additions & 32 deletions src/Auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { isDeepStrictEqual } from 'util';
import { getRequestObject, resolveError } from './triggers';
import { logger } from './logger';
import { LRUCache as LRU } from 'lru-cache';
import RestQuery from './RestQuery';
import RestWrite from './RestWrite';

Expand Down Expand Up @@ -67,6 +68,10 @@
return new Auth({ config, isMaster: false });
}

const throttle = new LRU({
max: 10000,
ttl: 500,
});
/**
* Checks whether session should be updated based on last update time & session length.
*/
Expand All @@ -78,44 +83,45 @@
return lastUpdated <= skipRange;
}

const throttle = {};
const renewSessionIfNeeded = async ({ config, session, sessionToken }) => {
if (!config?.extendSessionOnUse) {
return;
}
clearTimeout(throttle[sessionToken]);
throttle[sessionToken] = setTimeout(async () => {
try {
if (!session) {
const query = await RestQuery({
method: RestQuery.Method.get,
config,
auth: master(config),
runBeforeFind: false,
className: '_Session',
restWhere: { sessionToken },
restOptions: { limit: 1 },
});
const { results } = await query.execute();
session = results[0];
}
if (!shouldUpdateSessionExpiry(config, session) || !session) {
return;
}
const expiresAt = config.generateSessionExpiresAt();
await new RestWrite(
if (throttle.get(sessionToken)) {
return;
}
throttle.set(sessionToken, true);
try {
if (!session) {
const query = await RestQuery({
method: RestQuery.Method.get,
config,
master(config),
'_Session',
{ objectId: session.objectId },
{ expiresAt: Parse._encode(expiresAt) }
).execute();
} catch (e) {
if (e?.code !== Parse.Error.OBJECT_NOT_FOUND) {
logger.error('Could not update session expiry: ', e);
}
auth: master(config),
runBeforeFind: false,
className: '_Session',
restWhere: { sessionToken },
restOptions: { limit: 1 },
});
const { results } = await query.execute();
session = results[0];
}

if (!shouldUpdateSessionExpiry(config, session) || !session) {
return;
}
}, 500);
const expiresAt = config.generateSessionExpiresAt();
await new RestWrite(
config,
master(config),
'_Session',
{ objectId: session.objectId },
{ expiresAt: Parse._encode(expiresAt) }
).execute();
} catch (e) {
if (e?.code !== Parse.Error.OBJECT_NOT_FOUND) {
logger.error('Could not update session expiry: ', e);

Check warning on line 122 in src/Auth.js

View check run for this annotation

Codecov / codecov/patch

src/Auth.js#L121-L122

Added lines #L121 - L122 were not covered by tests
}
}
};

// Returns a promise that resolves to an Auth object
Expand Down
Loading