@quillsql/node 0.9.16 → 0.9.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,18 +1,13 @@
1
1
  export interface Mappable {
2
2
  get(key: string): Promise<string | null>;
3
3
  set(key: string, value: string, type?: string, ttl?: number): Promise<string | null>;
4
- lRange(key: string, start: number, stop: number): Promise<string[]>;
5
- rPush(key: string, elements: string[]): Promise<number>;
6
- expire(key: string, seconds: number): Promise<number | boolean>;
7
- del(...keys: string[]): Promise<number>;
8
- multi(): CacheTransaction;
9
- }
10
- export interface CacheTransaction {
11
- del(...keys: string[]): CacheTransaction;
12
- rPush(key: string, elements: string[]): CacheTransaction;
13
- expire(key: string, seconds: number): CacheTransaction;
14
- set(key: string, value: string, type?: string, ttl?: number): CacheTransaction;
15
- exec(): Promise<unknown>;
4
+ set(key: string, value: string, options: {
5
+ NX?: boolean;
6
+ XX?: boolean;
7
+ EX?: number;
8
+ PX?: number;
9
+ }): Promise<string | null>;
10
+ del(key: string): Promise<number>;
16
11
  }
17
12
  export interface CacheCredentials {
18
13
  username: string;
@@ -0,0 +1,13 @@
1
+ import { Mappable } from "../models/Cache";
2
+ export declare class Lock {
3
+ private readonly cacheLockKey;
4
+ private readonly lastCacheKey;
5
+ private readonly ttlSeconds;
6
+ private readonly cooldownMs;
7
+ constructor(clientId: string);
8
+ acquire(cache: Mappable): Promise<string>;
9
+ release(cache: Mappable, lockValue: string): Promise<void>;
10
+ releaseSafely(cache: Mappable, lockValue: string): Promise<void>;
11
+ persistCooldown(cache: Mappable): Promise<void>;
12
+ persistCooldownSafely(cache: Mappable): Promise<void>;
13
+ }
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ // A 2-part lock:
3
+ // 1) Redis Distributed lock ( 1 machine can hold it at a time )
4
+ // 2) 6-hour Cooldown
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.Lock = void 0;
16
+ class Lock {
17
+ constructor(clientId) {
18
+ this.ttlSeconds = 90 * 60; // 90 minutes
19
+ this.cooldownMs = 6 * 60 * 60 * 1000; // 6 hours
20
+ this.cacheLockKey = `quill:sdk:cache:lock:${clientId}`;
21
+ this.lastCacheKey = `quill:sdk:cache:locktime:${clientId}`;
22
+ }
23
+ acquire(cache) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ const lockValue = `${process.pid}:${Date.now()}:${Math.random().toString(36).slice(2)}`;
26
+ const acquired = yield cache.set(this.cacheLockKey, lockValue, { NX: true, EX: this.ttlSeconds });
27
+ if (!acquired) {
28
+ throw new Error(".cache() is being called by another instance already. Please try again later.");
29
+ }
30
+ const raw = yield cache.get(this.lastCacheKey);
31
+ const lastCacheRunAt = raw ? Number(raw) : NaN;
32
+ if (Number.isFinite(lastCacheRunAt) && Date.now() - lastCacheRunAt < this.cooldownMs) {
33
+ yield this.release(cache, lockValue);
34
+ throw new Error("Caching cooldown is active. Please try again later.");
35
+ }
36
+ return lockValue;
37
+ });
38
+ }
39
+ release(cache, lockValue) {
40
+ return __awaiter(this, void 0, void 0, function* () {
41
+ var _a;
42
+ const acquiredAtMs = Number((_a = lockValue.split(":")[1]) !== null && _a !== void 0 ? _a : "0");
43
+ if (acquiredAtMs > 0 && Date.now() - acquiredAtMs >= (this.ttlSeconds - 60) * 1000)
44
+ return;
45
+ if ((yield cache.get(this.cacheLockKey)) !== lockValue)
46
+ return;
47
+ yield cache.del(this.cacheLockKey);
48
+ });
49
+ }
50
+ releaseSafely(cache, lockValue) {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ try {
53
+ yield this.release(cache, lockValue);
54
+ }
55
+ catch (error) {
56
+ console.warn("Failed to release cache lock", error);
57
+ }
58
+ });
59
+ }
60
+ persistCooldown(cache) {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ yield cache.set(this.lastCacheKey, String(Date.now()), { EX: this.cooldownMs / 1000 });
63
+ });
64
+ }
65
+ persistCooldownSafely(cache) {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ try {
68
+ yield this.persistCooldown(cache);
69
+ }
70
+ catch (error) {
71
+ console.warn("Caching complete but failed to persist last cache run time", error);
72
+ }
73
+ });
74
+ }
75
+ }
76
+ exports.Lock = Lock;
77
+ //# sourceMappingURL=Lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Lock.js","sourceRoot":"","sources":["../../../src/utils/Lock.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,11 @@
1
1
  import { Mappable, CacheCredentials } from "../models/Cache";
2
2
  import { DatabaseConnection, DatabaseConnectionConfig, DatabaseConnectionType } from "./DatabaseHelper";
3
3
  export declare class CachedConnection {
4
- private static sharedRedisClients;
5
4
  databaseType: DatabaseConnectionType;
6
5
  readonly pool: DatabaseConnection;
7
- tenantIds: (string | number)[] | null;
8
6
  ttl: number;
9
7
  cache: Mappable | null;
8
+ isCacheJobRunning: boolean;
10
9
  private _isClosed;
11
10
  get isClosed(): boolean;
12
11
  /** Private constructor; use CachedConnection.create(...) */
@@ -14,9 +13,6 @@ export declare class CachedConnection {
14
13
  /** Async factory initializer */
15
14
  static create(databaseType: DatabaseConnectionType, config: DatabaseConnectionConfig, cacheConfig?: Partial<CacheCredentials>): Promise<CachedConnection>;
16
15
  query(text: string, overwriteCache?: boolean): Promise<any>;
17
- getCachedValue(key: string): Promise<string | null>;
18
- setCachedValue(key: string, value: string): Promise<void>;
19
- deleteCachedValue(key: string): Promise<void>;
20
16
  /**
21
17
  * Configures and returns a cache instance or null if none could be created.
22
18
  */
@@ -19,7 +19,7 @@ export class CachedConnection {
19
19
  /** Private constructor; use CachedConnection.create(...) */
20
20
  constructor(databaseType, config, cacheConfig = {}) {
21
21
  var _a;
22
- this.tenantIds = null;
22
+ this.isCacheJobRunning = false;
23
23
  this._isClosed = false;
24
24
  this.databaseType = databaseType;
25
25
  this.pool = connectToDatabase(databaseType, config);
@@ -36,7 +36,6 @@ export class CachedConnection {
36
36
  }
37
37
  query(text_1) {
38
38
  return __awaiter(this, arguments, void 0, function* (text, overwriteCache = false) {
39
- var _a;
40
39
  try {
41
40
  if (this.isClosed) {
42
41
  throw new Error("Connection is closed");
@@ -44,63 +43,27 @@ export class CachedConnection {
44
43
  if (!this.cache) {
45
44
  return yield runQueryByDatabase(this.databaseType, this.pool, text);
46
45
  }
47
- const keyBase = `${JSON.stringify((_a = this.tenantIds) !== null && _a !== void 0 ? _a : ["__NO_TENANT__"])}:${text}`;
48
- const fieldsKey = `${keyBase}:fields`;
49
- const rowsKey = `${keyBase}:rows`;
50
- const metaKey = `${keyBase}:meta`;
46
+ // `text` must be a tenant-scoped SQL query.
47
+ // Since runQueryByDatabase doesn't receive tenant information from any
48
+ // of its other parameters
49
+ const key = text;
51
50
  if (!overwriteCache) {
52
- const cachedMeta = yield this.cache.get(metaKey);
53
- if (cachedMeta !== null) {
54
- try {
55
- const parsedMeta = JSON.parse(cachedMeta);
56
- const [cachedFields, cachedRows] = yield Promise.all([
57
- this.cache.lRange(fieldsKey, 0, -1),
58
- this.cache.lRange(rowsKey, 0, -1),
59
- ]);
60
- if (parsedMeta.fieldsCount === cachedFields.length &&
61
- parsedMeta.rowsCount === cachedRows.length) {
62
- return {
63
- fields: cachedFields.map((item) => JSON.parse(item)),
64
- rows: cachedRows.map((item) => JSON.parse(item)),
65
- };
66
- }
67
- }
68
- catch (_b) {
69
- // Any parse/shape failure should invalidate this cache set.
70
- }
71
- yield this.cache.del(metaKey, fieldsKey, rowsKey);
72
- }
73
- }
74
- const newResult = yield runQueryByDatabase(this.databaseType, this.pool, text);
75
- if (!newResult) {
76
- return newResult;
51
+ let cachedResult = yield this.cache.get(key);
52
+ if (cachedResult)
53
+ return JSON.parse(cachedResult);
77
54
  }
55
+ const result = yield runQueryByDatabase(this.databaseType, this.pool, text);
78
56
  try {
79
- const fields = Array.isArray(newResult.fields) ? newResult.fields : [];
80
- const rows = Array.isArray(newResult.rows) ? newResult.rows : [];
81
- const fieldsPayload = fields.map((field) => JSON.stringify(field));
82
- const rowsPayload = rows.map((row) => JSON.stringify(row));
83
- const metaPayload = JSON.stringify({
84
- fieldsCount: fieldsPayload.length,
85
- rowsCount: rowsPayload.length,
86
- });
87
- const tx = this.cache.multi();
88
- tx.del(metaKey, fieldsKey, rowsKey);
89
- if (fieldsPayload.length) {
90
- tx.rPush(fieldsKey, fieldsPayload);
91
- tx.expire(fieldsKey, this.ttl);
92
- }
93
- if (rowsPayload.length) {
94
- tx.rPush(rowsKey, rowsPayload);
95
- tx.expire(rowsKey, this.ttl);
96
- }
97
- tx.set(metaKey, metaPayload, "EX", this.ttl);
98
- yield tx.exec();
57
+ yield this.cache.set(key, JSON.stringify(result), "EX", this.ttl);
99
58
  }
100
59
  catch (error) {
101
- console.warn("Redis Cache Set Failed: ", error);
60
+ const message = "Redis Cache Set Failed: " + String(error);
61
+ if (this.isCacheJobRunning) {
62
+ throw new Error(message);
63
+ }
64
+ console.warn(message); // This runs for general data fetching by customers
102
65
  }
103
- return newResult;
66
+ return result;
104
67
  }
105
68
  catch (err) {
106
69
  if (isSuperset(err, PgError)) {
@@ -112,56 +75,22 @@ export class CachedConnection {
112
75
  }
113
76
  });
114
77
  }
115
- getCachedValue(key) {
116
- return __awaiter(this, void 0, void 0, function* () {
117
- if (!this.cache || this.isClosed)
118
- return null;
119
- return yield this.cache.get(key);
120
- });
121
- }
122
- setCachedValue(key, value) {
123
- return __awaiter(this, void 0, void 0, function* () {
124
- if (!this.cache || this.isClosed)
125
- return;
126
- yield this.cache.set(key, value, "EX", this.ttl);
127
- });
128
- }
129
- deleteCachedValue(key) {
130
- return __awaiter(this, void 0, void 0, function* () {
131
- if (!this.cache || this.isClosed)
132
- return;
133
- yield this.cache.del(key);
134
- });
135
- }
136
78
  /**
137
79
  * Configures and returns a cache instance or null if none could be created.
138
80
  */
139
81
  getCache(_a) {
140
82
  return __awaiter(this, arguments, void 0, function* ({ username, password, host, port, cacheType, }) {
141
83
  if (cacheType === "redis" || cacheType === "rediss") {
142
- const sharedKey = JSON.stringify({
143
- cacheType,
144
- username: username || "",
145
- password: password || "",
146
- host: host || "",
147
- port: port || "",
148
- });
149
- const existingClient = CachedConnection.sharedRedisClients.get(sharedKey);
150
- if (existingClient) {
151
- return existingClient;
152
- }
153
84
  const client = createClient({
154
- username: username || "",
155
- password: password || "",
85
+ username: username || '',
86
+ password: password || '',
156
87
  socket: {
157
- host: host || "",
158
- port: port ? parseInt(port) : 0,
88
+ host: host || '',
89
+ port: port ? parseInt(port) : 0
159
90
  },
160
91
  });
161
92
  client.on("error", (err) => console.log("Redis Client Error", err));
162
93
  yield client.connect();
163
- // console.log("Redis connected to host:", host)
164
- CachedConnection.sharedRedisClients.set(sharedKey, client);
165
94
  return client;
166
95
  }
167
96
  return null;
@@ -177,5 +106,4 @@ export class CachedConnection {
177
106
  });
178
107
  }
179
108
  }
180
- CachedConnection.sharedRedisClients = new Map();
181
109
  //# sourceMappingURL=CachedConnection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CachedConnection.js","sourceRoot":"","sources":["../../../src/db/CachedConnection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CachedConnection.js","sourceRoot":"","sources":["../../../src/db/CachedConnection.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,21 @@ export interface QuillQueryResult {
19
19
  fields: any[];
20
20
  };
21
21
  }
22
+ export type QuillCacheResult = {
23
+ status: "failed";
24
+ error: string;
25
+ } | {
26
+ status: "complete";
27
+ cachedDashboards: string[];
28
+ failedDashboards: string[];
29
+ };
30
+ export interface QuillCacheParams {
31
+ tenants: QuillQueryParams["tenants"];
32
+ dashboards?: string[];
33
+ signal?: AbortSignal;
34
+ parallelQueries?: number;
35
+ maxRowsPerReport?: number;
36
+ }
22
37
  export type QuillStreamEvent = {
23
38
  type: "start";
24
39
  } | {
@@ -74,6 +89,7 @@ export declare class Quill implements AsyncDisposable {
74
89
  private baseUrl;
75
90
  private config;
76
91
  private initPromise;
92
+ private lock;
77
93
  constructor(data: {
78
94
  privateKey: string;
79
95
  databaseType: "snowflake";
@@ -107,9 +123,7 @@ export declare class Quill implements AsyncDisposable {
107
123
  metadataServerURL?: string;
108
124
  });
109
125
  private ensureReady;
110
- private getTenantMappedFlagsCacheKey;
111
- private getTenantMappedFlagsFromCache;
112
- private setTenantMappedFlagsCache;
126
+ cache({ tenants, dashboards, signal, parallelQueries, maxRowsPerReport, }: QuillCacheParams): Promise<QuillCacheResult>;
113
127
  query({ tenants, flags, metadata, filters, adminEnabled, }: QuillQueryParams): Promise<QuillQueryResult>;
114
128
  stream({ tenants, flags, metadata, filters, adminEnabled, signal, }: QuillStreamOptions): Promise<AsyncIterable<QuillStreamEvent>>;
115
129
  private applyLimit;