Skip to content
Snippets Groups Projects
Commit b363433a authored by Leonardo Christino's avatar Leonardo Christino
Browse files

feat: cache query result for one minute

parent 94f85415
No related branches found
Tags v1.18.0
1 merge request!25feat: cache query result for one minute
Pipeline #144984 passed
...@@ -17,4 +17,5 @@ SCHEMA_RETRIEVER=neo4j ...@@ -17,4 +17,5 @@ SCHEMA_RETRIEVER=neo4j
SMTP_HOST=smtp.office365.com SMTP_HOST=smtp.office365.com
SMTP_PORT=587 SMTP_PORT=587
SMTP_USER= SMTP_USER=
SMTP_PASSWORD= SMTP_PASSWORD=
\ No newline at end of file QUERY_CACHE_DURATION=
\ No newline at end of file
import { graphQueryBackend2graphQuery, type DbConnection, type QueryRequest } from 'ts-common'; import { graphQueryBackend2graphQuery, type DbConnection, type QueryRequest } from 'ts-common';
import { rabbitMq, redis, ums, type QueryExecutionTypes } from '../variables'; import { QUERY_CACHE_DURATION, rabbitMq, redis, ums, type QueryExecutionTypes } from '../variables';
import { log } from '../logger'; import { log } from '../logger';
import { QueryPublisher } from '../utils/queryPublisher'; import { QueryPublisher } from '../utils/queryPublisher';
import { query2Cypher } from '../utils/cypher/converter'; import { query2Cypher } from '../utils/cypher/converter';
...@@ -12,6 +12,27 @@ import { RabbitMqBroker } from 'ts-common/rabbitMq'; ...@@ -12,6 +12,27 @@ import { RabbitMqBroker } from 'ts-common/rabbitMq';
import { Neo4jConnection } from 'ts-common/neo4j'; import { Neo4jConnection } from 'ts-common/neo4j';
export const queryService = async (db: DbConnection, query: string): Promise<GraphQueryResultMetaFromBackend> => { export const queryService = async (db: DbConnection, query: string): Promise<GraphQueryResultMetaFromBackend> => {
let index = 0;
const disambiguatedQuery = query.replace(/\d{13}/g, () => (index++).toString());
const cacheKey = Bun.hash(JSON.stringify({ db: db, query: disambiguatedQuery })).toString();
if (QUERY_CACHE_DURATION === '') {
log.info('Query cache disabled, skipping cache check');
} else {
// check for cached results
log.debug('Checking cache for query, with cache ttl', QUERY_CACHE_DURATION, 'seconds');
const cached = await redis.client.get(cacheKey);
if (cached) {
log.info('Cache hit for query');
log.debug('Cache hit for query', disambiguatedQuery);
const buf = Buffer.from(cached, 'base64');
const inflated = Bun.gunzipSync(new Uint8Array(buf));
const dec = new TextDecoder();
const cachedMessage = JSON.parse(dec.decode(inflated)) as GraphQueryResultMetaFromBackend;
return cachedMessage;
}
}
// TODO: only neo4j is supported for now // TODO: only neo4j is supported for now
const connection = new Neo4jConnection(db); const connection = new Neo4jConnection(db);
try { try {
...@@ -21,6 +42,15 @@ export const queryService = async (db: DbConnection, query: string): Promise<Gra ...@@ -21,6 +42,15 @@ export const queryService = async (db: DbConnection, query: string): Promise<Gra
// calculate metadata // calculate metadata
const result = graphQueryBackend2graphQuery(graph); const result = graphQueryBackend2graphQuery(graph);
// cache result
const compressedMessage = Bun.gzipSync(JSON.stringify(result));
const base64Message = Buffer.from(compressedMessage).toString('base64');
if (QUERY_CACHE_DURATION !== '') {
// if cache enabled, cache the result
await redis.setWithExpire(cacheKey, base64Message, QUERY_CACHE_DURATION); // ttl in seconds
}
return result; return result;
} catch (error) { } catch (error) {
log.error('Error parsing query result:', query, error); log.error('Error parsing query result:', query, error);
......
...@@ -20,6 +20,8 @@ export const REDIS_HOST = Bun.env.REDIS_HOST || 'localhost'; ...@@ -20,6 +20,8 @@ export const REDIS_HOST = Bun.env.REDIS_HOST || 'localhost';
export const REDIS_PORT = parseInt(Bun.env.REDIS_PORT || '6379'); export const REDIS_PORT = parseInt(Bun.env.REDIS_PORT || '6379');
export const REDIS_PASSWORD = Bun.env.REDIS_PASSWORD || 'DevOnlyPass'; export const REDIS_PASSWORD = Bun.env.REDIS_PASSWORD || 'DevOnlyPass';
export const REDIS_SCHEMA_CACHE_DURATION = Bun.env.REDIS_SCHEMA_CACHE_DURATION || '60m'; export const REDIS_SCHEMA_CACHE_DURATION = Bun.env.REDIS_SCHEMA_CACHE_DURATION || '60m';
export const QUERY_CACHE_DURATION =
Bun.env.QUERY_CACHE_DURATION === '' || !Bun.env.QUERY_CACHE_DURATION ? '' : parseInt(Bun.env.QUERY_CACHE_DURATION);
export const redis = new RedisConnector(REDIS_PASSWORD, REDIS_HOST, REDIS_PORT); export const redis = new RedisConnector(REDIS_PASSWORD, REDIS_HOST, REDIS_PORT);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment