velocious 1.0.693 → 1.0.695
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.
- package/README.md +1 -1
- package/build/configuration-types.js +8 -0
- package/build/configuration.js +61 -1
- package/build/database/advisory-lock-runner.js +31 -0
- package/build/database/advisory-lock-telemetry.js +129 -0
- package/build/database/drivers/base.js +114 -2
- package/build/database/drivers/mssql/index.js +16 -0
- package/build/database/drivers/mysql/index.js +14 -0
- package/build/database/drivers/pgsql/index.js +17 -0
- package/build/database/drivers/sqlite/base.js +20 -0
- package/build/database/drivers/sqlite/index.js +33 -0
- package/build/database/record/index.js +28 -0
- package/build/routes/built-in/mcp/controller.js +63 -0
- package/build/src/configuration-types.d.ts +28 -0
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +8 -1
- package/build/src/configuration.d.ts +24 -1
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +57 -2
- package/build/src/database/advisory-lock-runner.d.ts +32 -0
- package/build/src/database/advisory-lock-runner.d.ts.map +1 -1
- package/build/src/database/advisory-lock-runner.js +29 -1
- package/build/src/database/advisory-lock-telemetry.d.ts +129 -0
- package/build/src/database/advisory-lock-telemetry.d.ts.map +1 -0
- package/build/src/database/advisory-lock-telemetry.js +122 -0
- package/build/src/database/drivers/base.d.ts +51 -0
- package/build/src/database/drivers/base.d.ts.map +1 -1
- package/build/src/database/drivers/base.js +104 -3
- package/build/src/database/drivers/mssql/index.d.ts +8 -0
- package/build/src/database/drivers/mssql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/index.js +13 -1
- package/build/src/database/drivers/mysql/index.d.ts +8 -0
- package/build/src/database/drivers/mysql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/index.js +13 -1
- package/build/src/database/drivers/pgsql/index.d.ts +8 -0
- package/build/src/database/drivers/pgsql/index.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/index.js +14 -1
- package/build/src/database/drivers/sqlite/base.d.ts +12 -0
- package/build/src/database/drivers/sqlite/base.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/base.js +18 -1
- package/build/src/database/drivers/sqlite/index.d.ts +15 -0
- package/build/src/database/drivers/sqlite/index.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.js +31 -1
- package/build/src/database/record/index.d.ts +54 -0
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +26 -1
- package/build/src/routes/built-in/mcp/controller.d.ts +14 -0
- package/build/src/routes/built-in/mcp/controller.d.ts.map +1 -0
- package/build/src/routes/built-in/mcp/controller.js +55 -0
- package/package.json +1 -1
- package/src/configuration-types.js +8 -0
- package/src/configuration.js +61 -1
- package/src/database/advisory-lock-runner.js +31 -0
- package/src/database/advisory-lock-telemetry.js +129 -0
- package/src/database/drivers/base.js +114 -2
- package/src/database/drivers/mssql/index.js +16 -0
- package/src/database/drivers/mysql/index.js +14 -0
- package/src/database/drivers/pgsql/index.js +17 -0
- package/src/database/drivers/sqlite/base.js +20 -0
- package/src/database/drivers/sqlite/index.js +33 -0
- package/src/database/record/index.js +28 -0
- package/src/routes/built-in/mcp/controller.js +63 -0
|
@@ -99,6 +99,38 @@ export default class AdvisoryLockRunner {
|
|
|
99
99
|
holdTimeoutMs?: number | null;
|
|
100
100
|
dedicatedConnection?: boolean;
|
|
101
101
|
}): Promise<T>;
|
|
102
|
+
/**
|
|
103
|
+
* Runs a callback if the advisory lock can be acquired without waiting;
|
|
104
|
+
* otherwise returns a `{acquired: false}` defer result instead of throwing.
|
|
105
|
+
*
|
|
106
|
+
* This is the non-throwing counterpart of `withAdvisoryLockOrFail` for hot
|
|
107
|
+
* paths: "holder busy, defer me" is a first-class outcome, so a contended
|
|
108
|
+
* lock produces zero exception traffic and — because the probe is a single
|
|
109
|
+
* immediate try-acquire — zero pinned connections. Callers reschedule via
|
|
110
|
+
* their own event-driven retry machinery. The result form is identical
|
|
111
|
+
* across tiers: the driver's `tryAcquireAdvisoryLock` maps per-tier (MySQL
|
|
112
|
+
* `GET_LOCK(name, 0)`, PostgreSQL `pg_try_advisory_lock`, SQL Server
|
|
113
|
+
* `sp_getapplock @LockTimeout = 0`, SQLite process-local queue, SQLite Node
|
|
114
|
+
* file lock), so a caller never branches on the backend.
|
|
115
|
+
* @template T
|
|
116
|
+
* @param {string} name - Lock name.
|
|
117
|
+
* @param {(args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
118
|
+
* @param {{holdTimeoutMs?: number | null, dedicatedConnection?: boolean}} [args] - Hold timeout options.
|
|
119
|
+
* @returns {Promise<{acquired: true, result: T} | {acquired: false, reason: "contended", lockName: string}>} - Either the held-callback result or the defer outcome.
|
|
120
|
+
*/
|
|
121
|
+
withAdvisoryLockOrDefer<T>(name: string, callback: (args?: {
|
|
122
|
+
control: import("awaitery/build/timeout.js").TimeoutControl;
|
|
123
|
+
}) => Promise<T>, args?: {
|
|
124
|
+
holdTimeoutMs?: number | null;
|
|
125
|
+
dedicatedConnection?: boolean;
|
|
126
|
+
}): Promise<{
|
|
127
|
+
acquired: true;
|
|
128
|
+
result: T;
|
|
129
|
+
} | {
|
|
130
|
+
acquired: false;
|
|
131
|
+
reason: "contended";
|
|
132
|
+
lockName: string;
|
|
133
|
+
}>;
|
|
102
134
|
/**
|
|
103
135
|
* Runs the lock holder callback and releases the lock from its owning connection.
|
|
104
136
|
* @template T
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advisory-lock-runner.d.ts","sourceRoot":"","sources":["../../../src/database/advisory-lock-runner.js"],"names":[],"mappings":"AAIA;;GAEG;AACH,cAAM,wBAAyB,SAAQ,KAAK;IASnC,QAAQ;IARf;;;;OAIG;IACH,YAAY,OAAO,EAHR,MAGQ,EAAE,EAAC,IAAI,EAAC,EAFhB;QAAC,IAAI,EAAE,MAAM,CAAA;KAEG,EAI1B;CACF;AAED;;GAEG;AACH,cAAM,qBAAsB,SAAQ,KAAK;IAShC,QAAQ;IARf;;;;OAIG;IACH,YAAY,OAAO,EAHR,MAGQ,EAAE,EAAC,IAAI,EAAC,EAFhB;QAAC,IAAI,EAAE,MAAM,CAAA;KAEG,EAI1B;CACF;AAED;;GAEG;AACH,cAAM,4BAA6B,SAAQ,KAAK;IASvC,QAAQ;IARf;;;;OAIG;IACH,YAAY,OAAO,EAHR,MAGQ,EAAE,EAAC,IAAI,EAAC,EAFhB;QAAC,IAAI,EAAE,MAAM,CAAA;KAEG,EAI1B;CACF;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAkB;IAM9B,aAAa;IACb,kBAAkB,QAJmE,OAAO,mBAAmB,EAAE,OAAO;IAKxH,kBAAkB;IAPzB;;;OAGG;IACH,YAAY,EAAC,aAAa,EAAE,kBAAkB,EAAE,kBAAkB,EAAC,EAFxD;QAAC,aAAa,EAAE,OAAO,qBAAqB,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,MAAM,OAAO,mBAAmB,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAExF,EAIlE;IAED;;;;;;;;;;;;;;OAcG;IACG,gBAAgB,CANT,CAAC,EAMS,IAAI,EALhB,MAKgB,EAAE,QAAQ,EAJ1B,CAAC,IAAI,CAAC,EAAE;QAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;KAAC,KAAK,OAAO,CAAC,CAAC,CAIzD,EAAE,IAAI,AAHxC,CACA,EADQ;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;KAGnD,GAFnC,OAAO,CAAC,CAAC,CAAC,CAYtB;IAED;;;;;;;;;;;;OAYG;IACG,sBAAsB,CANf,CAAC,EAMe,IAAI,EALtB,MAKsB,EAAE,QAAQ,EAJhC,CAAC,IAAI,CAAC,EAAE;QAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;KAAC,KAAK,OAAO,CAAC,CAAC,CAInD,EAAE,IAAI,AAH9C,CACA,EADQ;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;KAGlB,GAFzC,OAAO,CAAC,CAAC,CAAC,CAYtB;IAED;;;;;OAKG;IACG,iBAAiB,CAJV,CAAC,EAIU,EAAC,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,IAAI,EAAC,EAHxD;QAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE;YAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;SAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;QAAC,UAAU,EAAE,OAAO,mBAAmB,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAGrI,GAFtD,OAAO,CAAC,CAAC,CAAC,CAQtB;IAED;;;;;;;OAOG;IACG,kBAAkB,CALX,CAAC,EAKW,IAAI,EAJlB;QAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAI3C,EAAE,QAAQ,EAH5B,CAAC,UAAU,EAAE,OAAO,mBAAmB,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAGlC,GAF1B,OAAO,CAAC,CAAC,CAAC,CAUtB;IAED;;;;;;OAMG;IACG,uBAAuB,CAJhB,CAAC,EAIgB,QAAQ,EAH3B,CAAC,UAAU,EAAE,OAAO,mBAAmB,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAGnC,GAFzB,OAAO,CAAC,CAAC,CAAC,CAuBtB;IAED;;;;;;;;;;;;;OAaG;IACH,OAAa,8BAA8B,CAN9B,CAAC,EAM8B,IAAI,EALrC,MAKqC,EAAE,QAAQ,EAJ/C,CAAC,IAAI,CAAC,EAAE;QAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;KAAC,KAAK,OAAO,CAAC,CAAC,CAIpC,EAAE,aAAa,AAHtE,CACA,EADQ,MAAM,GAAG,IAGqD,GAF5D,OAAO,CAAC,CAAC,CAAC,CAwBtB;CACF;AAED,OAAO,EAAC,qBAAqB,EAAE,4BAA4B,EAAE,wBAAwB,EAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"advisory-lock-runner.d.ts","sourceRoot":"","sources":["../../../src/database/advisory-lock-runner.js"],"names":[],"mappings":"AAIA;;GAEG;AACH,cAAM,wBAAyB,SAAQ,KAAK;IASnC,QAAQ;IARf;;;;OAIG;IACH,YAAY,OAAO,EAHR,MAGQ,EAAE,EAAC,IAAI,EAAC,EAFhB;QAAC,IAAI,EAAE,MAAM,CAAA;KAEG,EAI1B;CACF;AAED;;GAEG;AACH,cAAM,qBAAsB,SAAQ,KAAK;IAShC,QAAQ;IARf;;;;OAIG;IACH,YAAY,OAAO,EAHR,MAGQ,EAAE,EAAC,IAAI,EAAC,EAFhB;QAAC,IAAI,EAAE,MAAM,CAAA;KAEG,EAI1B;CACF;AAED;;GAEG;AACH,cAAM,4BAA6B,SAAQ,KAAK;IASvC,QAAQ;IARf;;;;OAIG;IACH,YAAY,OAAO,EAHR,MAGQ,EAAE,EAAC,IAAI,EAAC,EAFhB;QAAC,IAAI,EAAE,MAAM,CAAA;KAEG,EAI1B;CACF;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAkB;IAM9B,aAAa;IACb,kBAAkB,QAJmE,OAAO,mBAAmB,EAAE,OAAO;IAKxH,kBAAkB;IAPzB;;;OAGG;IACH,YAAY,EAAC,aAAa,EAAE,kBAAkB,EAAE,kBAAkB,EAAC,EAFxD;QAAC,aAAa,EAAE,OAAO,qBAAqB,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,MAAM,OAAO,mBAAmB,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAExF,EAIlE;IAED;;;;;;;;;;;;;;OAcG;IACG,gBAAgB,CANT,CAAC,EAMS,IAAI,EALhB,MAKgB,EAAE,QAAQ,EAJ1B,CAAC,IAAI,CAAC,EAAE;QAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;KAAC,KAAK,OAAO,CAAC,CAAC,CAIzD,EAAE,IAAI,AAHxC,CACA,EADQ;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;KAGnD,GAFnC,OAAO,CAAC,CAAC,CAAC,CAYtB;IAED;;;;;;;;;;;;OAYG;IACG,sBAAsB,CANf,CAAC,EAMe,IAAI,EALtB,MAKsB,EAAE,QAAQ,EAJhC,CAAC,IAAI,CAAC,EAAE;QAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;KAAC,KAAK,OAAO,CAAC,CAAC,CAInD,EAAE,IAAI,AAH9C,CACA,EADQ;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;KAGlB,GAFzC,OAAO,CAAC,CAAC,CAAC,CAYtB;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACG,uBAAuB,CANhB,CAAC,EAMgB,IAAI,EALvB,MAKuB,EAAE,QAAQ,EAJjC,CAAC,IAAI,CAAC,EAAE;QAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;KAAC,KAAK,OAAO,CAAC,CAAC,CAIlD,EAAE,IAAI,AAH/C,CACA,EADQ;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;KAGjB,GAF1C,OAAO,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,CAAA;KAAC,GAAG;QAAC,QAAQ,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,WAAW,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,CAAC,CAY3G;IAED;;;;;OAKG;IACG,iBAAiB,CAJV,CAAC,EAIU,EAAC,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,IAAI,EAAC,EAHxD;QAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE;YAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;SAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;QAAC,UAAU,EAAE,OAAO,mBAAmB,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAGrI,GAFtD,OAAO,CAAC,CAAC,CAAC,CAQtB;IAED;;;;;;;OAOG;IACG,kBAAkB,CALX,CAAC,EAKW,IAAI,EAJlB;QAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAI3C,EAAE,QAAQ,EAH5B,CAAC,UAAU,EAAE,OAAO,mBAAmB,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAGlC,GAF1B,OAAO,CAAC,CAAC,CAAC,CAUtB;IAED;;;;;;OAMG;IACG,uBAAuB,CAJhB,CAAC,EAIgB,QAAQ,EAH3B,CAAC,UAAU,EAAE,OAAO,mBAAmB,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAGnC,GAFzB,OAAO,CAAC,CAAC,CAAC,CAuBtB;IAED;;;;;;;;;;;;;OAaG;IACH,OAAa,8BAA8B,CAN9B,CAAC,EAM8B,IAAI,EALrC,MAKqC,EAAE,QAAQ,EAJ/C,CAAC,IAAI,CAAC,EAAE;QAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,cAAc,CAAA;KAAC,KAAK,OAAO,CAAC,CAAC,CAIpC,EAAE,aAAa,AAHtE,CACA,EADQ,MAAM,GAAG,IAGqD,GAF5D,OAAO,CAAC,CAAC,CAAC,CAwBtB;CACF;AAED,OAAO,EAAC,qBAAqB,EAAE,4BAA4B,EAAE,wBAAwB,EAAC,CAAA"}
|
|
@@ -106,6 +106,34 @@ export default class AdvisoryLockRunner {
|
|
|
106
106
|
return await this.runLockedCallback({ callback, connection, holdTimeoutMs: args.holdTimeoutMs, name });
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Runs a callback if the advisory lock can be acquired without waiting;
|
|
111
|
+
* otherwise returns a `{acquired: false}` defer result instead of throwing.
|
|
112
|
+
*
|
|
113
|
+
* This is the non-throwing counterpart of `withAdvisoryLockOrFail` for hot
|
|
114
|
+
* paths: "holder busy, defer me" is a first-class outcome, so a contended
|
|
115
|
+
* lock produces zero exception traffic and — because the probe is a single
|
|
116
|
+
* immediate try-acquire — zero pinned connections. Callers reschedule via
|
|
117
|
+
* their own event-driven retry machinery. The result form is identical
|
|
118
|
+
* across tiers: the driver's `tryAcquireAdvisoryLock` maps per-tier (MySQL
|
|
119
|
+
* `GET_LOCK(name, 0)`, PostgreSQL `pg_try_advisory_lock`, SQL Server
|
|
120
|
+
* `sp_getapplock @LockTimeout = 0`, SQLite process-local queue, SQLite Node
|
|
121
|
+
* file lock), so a caller never branches on the backend.
|
|
122
|
+
* @template T
|
|
123
|
+
* @param {string} name - Lock name.
|
|
124
|
+
* @param {(args?: {control: import("awaitery/build/timeout.js").TimeoutControl}) => Promise<T>} callback - Callback to invoke while the lock is held.
|
|
125
|
+
* @param {{holdTimeoutMs?: number | null, dedicatedConnection?: boolean}} [args] - Hold timeout options.
|
|
126
|
+
* @returns {Promise<{acquired: true, result: T} | {acquired: false, reason: "contended", lockName: string}>} - Either the held-callback result or the defer outcome.
|
|
127
|
+
*/
|
|
128
|
+
async withAdvisoryLockOrDefer(name, callback, args = {}) {
|
|
129
|
+
return await this.withLockConnection(args, async (connection) => {
|
|
130
|
+
const acquired = await connection.tryAcquireAdvisoryLock(name);
|
|
131
|
+
if (!acquired)
|
|
132
|
+
return { acquired: false, reason: "contended", lockName: name };
|
|
133
|
+
const result = await this.runLockedCallback({ callback, connection, holdTimeoutMs: args.holdTimeoutMs, name });
|
|
134
|
+
return { acquired: true, result };
|
|
135
|
+
});
|
|
136
|
+
}
|
|
109
137
|
/**
|
|
110
138
|
* Runs the lock holder callback and releases the lock from its owning connection.
|
|
111
139
|
* @template T
|
|
@@ -202,4 +230,4 @@ export default class AdvisoryLockRunner {
|
|
|
202
230
|
}
|
|
203
231
|
}
|
|
204
232
|
export { AdvisoryLockBusyError, AdvisoryLockHoldTimeoutError, AdvisoryLockTimeoutError };
|
|
205
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2aXNvcnktbG9jay1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvYWR2aXNvcnktbG9jay1ydW5uZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sT0FBTyxFQUFFLEVBQUMsWUFBWSxFQUFDLE1BQU0sMkJBQTJCLENBQUE7QUFFL0Q7O0dBRUc7QUFDSCxNQUFNLHdCQUF5QixTQUFRLEtBQUs7SUFDMUM7Ozs7T0FJRztJQUNILFlBQVksT0FBTyxFQUFFLEVBQUMsSUFBSSxFQUFDO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNkLElBQUksQ0FBQyxJQUFJLEdBQUcsMEJBQTBCLENBQUE7UUFDdEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFDdEIsQ0FBQztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLHFCQUFzQixTQUFRLEtBQUs7SUFDdkM7Ozs7T0FJRztJQUNILFlBQVksT0FBTyxFQUFFLEVBQUMsSUFBSSxFQUFDO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNkLElBQUksQ0FBQyxJQUFJLEdBQUcsdUJBQXVCLENBQUE7UUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFDdEIsQ0FBQztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLDRCQUE2QixTQUFRLEtBQUs7SUFDOUM7Ozs7T0FJRztJQUNILFlBQVksT0FBTyxFQUFFLEVBQUMsSUFBSSxFQUFDO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNkLElBQUksQ0FBQyxJQUFJLEdBQUcsOEJBQThCLENBQUE7UUFDMUMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFDdEIsQ0FBQztDQUNGO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sa0JBQWtCO0lBQ3JDOzs7T0FHRztJQUNILFlBQVksRUFB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O29CQUNILE9BQU8sTUFBTSxRQUFRLENBQUMsRUFBQyxPQUFPLEVBQUMsQ0FBQyxDQUFBO2dCQUNsQyxDQUFDO3dCQUFTLENBQUM7b0JBQ1QsZUFBZSxHQUFHLElBQUksQ0FBQTtnQkFDeEIsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFBO1FBQ0osQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsZUFBZSxJQUFJLEtBQUssWUFBWSxZQUFZLEVBQUUsQ0FBQztnQkFDdEQsTUFBTSxJQUFJLDRCQUE0QixDQUFDLGlCQUFpQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsYUFBYSxJQUFJLEVBQUUsRUFBQyxJQUFJLEVBQUMsQ0FBQyxDQUFBO1lBQzdILENBQUM7WUFFRCxNQUFNLEtBQUssQ0FBQTtRQUNiLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFFRCxPQUFPLEVBQUMscUJBQXFCLEVBQUUsNEJBQTRCLEVBQUUsd0JBQXdCLEVBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgdGltZW91dCwge1RpbWVvdXRFcnJvcn0gZnJvbSBcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIlxuXG4vKipcbiAqIFRocm93biB3aGVuIGFuIGFkdmlzb3J5IGxvY2sgY291bGQgbm90IGJlIGFjcXVpcmVkIGJlZm9yZSBgdGltZW91dE1zYCBlbGFwc2VkLlxuICovXG5jbGFzcyBBZHZpc29yeUxvY2tUaW1lb3V0RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIEVycm9yIG1lc3NhZ2UuXG4gICAqIEBwYXJhbSB7e25hbWU6IHN0cmluZ319IGFyZ3MgLSBUaGUgYWR2aXNvcnkgbG9jayBuYW1lIHRoYXQgdGltZWQgb3V0LlxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSwge25hbWV9KSB7XG4gICAgc3VwZXIobWVzc2FnZSlcbiAgICB0aGlzLm5hbWUgPSBcIkFkdmlzb3J5TG9ja1RpbWVvdXRFcnJvclwiXG4gICAgdGhpcy5sb2NrTmFtZSA9IG5hbWVcbiAgfVxufVxuXG4vKipcbiAqIFRocm93biB3aGVuIGB3aXRoQWR2aXNvcnlMb2NrT3JGYWlsYCBmaW5kcyB0aGUgbG9jayBhbHJlYWR5IGhlbGQuXG4gKi9cbmNsYXNzIEFkdmlzb3J5TG9ja0J1c3lFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHBhcmFtIHt7bmFtZTogc3RyaW5nfX0gYXJncyAtIFRoZSBhZHZpc29yeSBsb2NrIG5hbWUgdGhhdCB3YXMgYWxyZWFkeSBoZWxkLlxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSwge25hbWV9KSB7XG4gICAgc3VwZXIobWVzc2FnZSlcbiAgICB0aGlzLm5hbWUgPSBcIkFkdmlzb3J5TG9ja0J1c3lFcnJvclwiXG4gICAgdGhpcy5sb2NrTmFtZSA9IG5hbWVcbiAgfVxufVxuXG4vKipcbiAqIFRocm93biB3aGVuIGEgY2FsbGJhY2sgaG9sZHMgYW4gYWR2aXNvcnkgbG9jayBsb25nZXIgdGhhbiBgaG9sZFRpbWVvdXRNc2AuXG4gKi9cbmNsYXNzIEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIEVycm9yIG1lc3NhZ2UuXG4gICAqIEBwYXJhbSB7e25hbWU6IHN0cmluZ319IGFyZ3MgLSBUaGUgYWR2aXNvcnkgbG9jayBuYW1lIHdob3NlIGhvbGQgdGltZWQgb3V0LlxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSwge25hbWV9KSB7XG4gICAgc3VwZXIobWVzc2FnZSlcbiAgICB0aGlzLm5hbWUgPSBcIkFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0RXJyb3JcIlxuICAgIHRoaXMubG9ja05hbWUgPSBuYW1lXG4gIH1cbn1cblxuLyoqXG4gKiBSdW5zIGFkdmlzb3J5IGxvY2tzIG9uIHRoZSBjYWxsZXIgY29ubmVjdGlvbiBieSBkZWZhdWx0LCB1c2luZyBhIGRlZGljYXRlZFxuICogbG9jayBjb25uZWN0aW9uIHdoZW4gYGRlZGljYXRlZENvbm5lY3Rpb25gIGlzIHJlcXVlc3RlZCBvciB3aGVuIGEgcG9zaXRpdmVcbiAqIGhvbGQgdGltZW91dCBuZWVkcyBzZXBhcmF0ZSBvd25lcnNoaXAuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFkdmlzb3J5TG9ja1J1bm5lciB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGFkdmlzb3J5LWxvY2sgcnVubmVyIGZvciBvbmUgbW9kZWwgZGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHt7Y29uZmlndXJhdGlvbjogaW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0LCBjb25uZWN0aW9uUHJvdmlkZXI6ICgpID0+IGltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQsIGRhdGFiYXNlSWRlbnRpZmllcjogc3RyaW5nfX0gYXJncyAtIFJ1bm5lciBkZXBlbmRlbmNpZXMuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7Y29uZmlndXJhdGlvbiwgY29ubmVjdGlvblByb3ZpZGVyLCBkYXRhYmFzZUlkZW50aWZpZXJ9KSB7XG4gICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIHRoaXMuY29ubmVjdGlvblByb3ZpZGVyID0gY29ubmVjdGlvblByb3ZpZGVyXG4gICAgdGhpcy5kYXRhYmFzZUlkZW50aWZpZXIgPSBkYXRhYmFzZUlkZW50aWZpZXJcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGEgY2FsbGJhY2sgYWZ0ZXIgYWNxdWlyaW5nIHRoZSBhZHZpc29yeSBsb2NrLCB3YWl0aW5nIHVwIHRvIGB0aW1lb3V0TXNgLlxuICAgKiBXaGVuIGBkZWRpY2F0ZWRDb25uZWN0aW9uYCBpcyB0cnVlIHRoZSBsb2NrIGlzIGFjcXVpcmVkIG9uIGEgc3Bhd25lZFxuICAgKiBjb25uZWN0aW9uIHRoYXQgaXMgcmVsZWFzZWQgYWZ0ZXIgdGhlIGNhbGxiYWNrIGZpbmlzaGVzLCB3aGlsZSB0aGUgY2FsbGJhY2tcbiAgICogaXRzZWxmIHN0aWxsIHJ1bnMgYWdhaW5zdCB0aGUgY2FsbGVyL21vZGVsIGNvbm5lY3Rpb24uIFdoZW4gYSBgaG9sZFRpbWVvdXRNc2BcbiAgICogaXMgc2V0IHRoZSBjYWxsYmFjayByZWNlaXZlcyBhIGBUaW1lb3V0Q29udHJvbGAgZnJvbSBhd2FpdGVyeSBmb3IgY29vcGVyYXRpdmVcbiAgICogY2FuY2VsbGF0aW9uIChgY29udHJvbC5jaGVjaygpYCwgYGNvbnRyb2wuc2lnbmFsYCwgYGNvbnRyb2wudGltZWRPdXRgLFxuICAgKiBgY29udHJvbC5yZW1haW5pbmcoKWApOyBhIGRlZGljYXRlZCBjb25uZWN0aW9uIGlzIGFsc28gdXNlZCBzbyB0aW1lb3V0XG4gICAqIGNsZWFudXAgY2FuIHJlbGVhc2UgdGhlIGxvY2sgZXZlbiBpZiBjYWxsYmFjayBkYXRhYmFzZSB3b3JrIGlzIHN0dWNrLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZS5cbiAgICogQHBhcmFtIHsoYXJncz86IHtjb250cm9sOiBpbXBvcnQoXCJhd2FpdGVyeS9idWlsZC90aW1lb3V0LmpzXCIpLlRpbWVvdXRDb250cm9sfSkgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBpbnZva2Ugd2hpbGUgdGhlIGxvY2sgaXMgaGVsZC5cbiAgICogQHBhcmFtIHt7dGltZW91dE1zPzogbnVtYmVyIHwgbnVsbCwgaG9sZFRpbWVvdXRNcz86IG51bWJlciB8IG51bGwsIGRlZGljYXRlZENvbm5lY3Rpb24/OiBib29sZWFufX0gW2FyZ3NdIC0gTG9jayBhbmQgaG9sZCB0aW1lb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHdpdGhBZHZpc29yeUxvY2sobmFtZSwgY2FsbGJhY2ssIGFyZ3MgPSB7fSkge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhMb2NrQ29ubmVjdGlvbihhcmdzLCBhc3luYyAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgY29uc3QgYWNxdWlyZWQgPSBhd2FpdCBjb25uZWN0aW9uLmFjcXVpcmVBZHZpc29yeUxvY2sobmFtZSwgYXJncylcblxuICAgICAgaWYgKCFhY3F1aXJlZCkge1xuICAgICAgICB0aHJvdyBuZXcgQWR2aXNvcnlMb2NrVGltZW91dEVycm9yKGBUaW1lZCBvdXQgd2FpdGluZyBmb3IgYWR2aXNvcnkgbG9jayAke0pTT04uc3RyaW5naWZ5KG5hbWUpfWAsIHtuYW1lfSlcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucnVuTG9ja2VkQ2FsbGJhY2soe2NhbGxiYWNrLCBjb25uZWN0aW9uLCBob2xkVGltZW91dE1zOiBhcmdzLmhvbGRUaW1lb3V0TXMsIG5hbWV9KVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBhIGNhbGxiYWNrIG9ubHkgaWYgdGhlIGFkdmlzb3J5IGxvY2sgY2FuIGJlIGFjcXVpcmVkIGltbWVkaWF0ZWx5LlxuICAgKiBXaGVuIGBkZWRpY2F0ZWRDb25uZWN0aW9uYCBpcyB0cnVlIHRoZSBsb2NrIGlzIGFjcXVpcmVkIG9uIGEgc3Bhd25lZFxuICAgKiBjb25uZWN0aW9uIHRoYXQgaXMgcmVsZWFzZWQgYWZ0ZXIgdGhlIGNhbGxiYWNrIGZpbmlzaGVzLCB3aGlsZSB0aGUgY2FsbGJhY2tcbiAgICogaXRzZWxmIHN0aWxsIHJ1bnMgYWdhaW5zdCB0aGUgY2FsbGVyL21vZGVsIGNvbm5lY3Rpb24uIFdoZW4gYSBgaG9sZFRpbWVvdXRNc2BcbiAgICogaXMgc2V0IHRoZSBjYWxsYmFjayByZWNlaXZlcyBhIGBUaW1lb3V0Q29udHJvbGAgZnJvbSBhd2FpdGVyeSBmb3IgY29vcGVyYXRpdmVcbiAgICogY2FuY2VsbGF0aW9uLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZS5cbiAgICogQHBhcmFtIHsoYXJncz86IHtjb250cm9sOiBpbXBvcnQoXCJhd2FpdGVyeS9idWlsZC90aW1lb3V0LmpzXCIpLlRpbWVvdXRDb250cm9sfSkgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBpbnZva2Ugd2hpbGUgdGhlIGxvY2sgaXMgaGVsZC5cbiAgICogQHBhcmFtIHt7aG9sZFRpbWVvdXRNcz86IG51bWJlciB8IG51bGwsIGRlZGljYXRlZENvbm5lY3Rpb24/OiBib29sZWFufX0gW2FyZ3NdIC0gSG9sZCB0aW1lb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHdpdGhBZHZpc29yeUxvY2tPckZhaWwobmFtZSwgY2FsbGJhY2ssIGFyZ3MgPSB7fSkge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhMb2NrQ29ubmVjdGlvbihhcmdzLCBhc3luYyAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgY29uc3QgYWNxdWlyZWQgPSBhd2FpdCBjb25uZWN0aW9uLnRyeUFjcXVpcmVBZHZpc29yeUxvY2sobmFtZSlcblxuICAgICAgaWYgKCFhY3F1aXJlZCkge1xuICAgICAgICB0aHJvdyBuZXcgQWR2aXNvcnlMb2NrQnVzeUVycm9yKGBBZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IGlzIGFscmVhZHkgaGVsZGAsIHtuYW1lfSlcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucnVuTG9ja2VkQ2FsbGJhY2soe2NhbGxiYWNrLCBjb25uZWN0aW9uLCBob2xkVGltZW91dE1zOiBhcmdzLmhvbGRUaW1lb3V0TXMsIG5hbWV9KVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyB0aGUgbG9jayBob2xkZXIgY2FsbGJhY2sgYW5kIHJlbGVhc2VzIHRoZSBsb2NrIGZyb20gaXRzIG93bmluZyBjb25uZWN0aW9uLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3tjYWxsYmFjazogKGFyZ3M/OiB7Y29udHJvbDogaW1wb3J0KFwiYXdhaXRlcnkvYnVpbGQvdGltZW91dC5qc1wiKS5UaW1lb3V0Q29udHJvbH0pID0+IFByb21pc2U8VD4sIGNvbm5lY3Rpb246IGltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQsIGhvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsLCBuYW1lOiBzdHJpbmd9fSBhcmdzIC0gTG9ja2VkIGNhbGxiYWNrIGFyZ3MuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHJ1bkxvY2tlZENhbGxiYWNrKHtjYWxsYmFjaywgY29ubmVjdGlvbiwgaG9sZFRpbWVvdXRNcywgbmFtZX0pIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IEFkdmlzb3J5TG9ja1J1bm5lci5ydW5XaXRoQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXQobmFtZSwgY2FsbGJhY2ssIGhvbGRUaW1lb3V0TXMpXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucmVsZWFzZUFkdmlzb3J5TG9jayhuYW1lKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGxvY2sgd29yayBvbiB0aGUgY2FsbGVyIGNvbm5lY3Rpb24gdW5sZXNzIGBkZWRpY2F0ZWRDb25uZWN0aW9uYCBpc1xuICAgKiByZXF1ZXN0ZWQgb3IgYSBwb3NpdGl2ZSBob2xkIHRpbWVvdXQgbmVlZHMgaXRzIG93biBsb2NrIGNvbm5lY3Rpb24uXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7e2RlZGljYXRlZENvbm5lY3Rpb24/OiBib29sZWFuLCBob2xkVGltZW91dE1zPzogbnVtYmVyIHwgbnVsbH19IGFyZ3MgLSBMb2NrIGNvbm5lY3Rpb24gb3B0aW9ucy5cbiAgICogQHBhcmFtIHsoY29ubmVjdGlvbjogaW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCkgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayByZWNlaXZpbmcgdGhlIGNvbm5lY3Rpb24gdGhhdCBvd25zIHRoZSBhZHZpc29yeSBsb2NrLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoTG9ja0Nvbm5lY3Rpb24oYXJncywgY2FsbGJhY2spIHtcbiAgICBjb25zdCBob2xkVGltZW91dE1zID0gYXJncy5ob2xkVGltZW91dE1zXG5cbiAgICBpZiAoYXJncy5kZWRpY2F0ZWRDb25uZWN0aW9uIHx8IChob2xkVGltZW91dE1zICYmIGhvbGRUaW1lb3V0TXMgPiAwKSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMud2l0aERlZGljYXRlZENvbm5lY3Rpb24oY2FsbGJhY2spXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IGNhbGxiYWNrKHRoaXMuY29ubmVjdGlvblByb3ZpZGVyKCkpXG4gIH1cblxuICAvKipcbiAgICogU3Bhd25zIGEgZGVkaWNhdGVkIGxvY2sgY29ubmVjdGlvbiBhbmQgY2xvc2VzIGl0IGFmdGVyIGxvY2sgd29yayBjb21wbGV0ZXNcbiAgICogd2hlbiB0aGUgc3Bhd25lZCBkcml2ZXIgb3ducyB0aGUgdW5kZXJseWluZyBwaHlzaWNhbCBjb25uZWN0aW9uLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0geyhjb25uZWN0aW9uOiBpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0KSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdGhlIGRlZGljYXRlZCBsb2NrIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHdpdGhEZWRpY2F0ZWRDb25uZWN0aW9uKGNhbGxiYWNrKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZVBvb2wodGhpcy5kYXRhYmFzZUlkZW50aWZpZXIpLnNwYXduQ29ubmVjdGlvbigpXG5cbiAgICAvLyBUaGUgc3Bhd25lZCBkcml2ZXIgb3ducyBpdHMgcGh5c2ljYWwgY29ubmVjdGlvbiB1bmxlc3MgaXQgYm9ycm93cyBhIHNoYXJlZCBvbmVcbiAgICAvLyB2aWEgYGdldENvbm5lY3Rpb25gLiBBbiBvd25lZCBjb25uZWN0aW9uIGxpdmVzIG91dHNpZGUgdGhlIHBvb2xzJyB0cmFja2VkIHNldHMsXG4gICAgLy8gc28gcmVnaXN0ZXIgaXQgd2hpbGUgdGhlIGxvY2sgaXMgaGVsZDogYSBzaHV0ZG93biB0aGVuIGNsb3NlcyBpdCAocmVsZWFzaW5nIHRoZVxuICAgIC8vIGxvY2spIGluc3RlYWQgb2Ygb3JwaGFuaW5nIGEgaGFsZi1vcGVuIHNlc3Npb24gdW50aWwgdGhlIERCIGB3YWl0X3RpbWVvdXRgLlxuICAgIGNvbnN0IG93bnNDb25uZWN0aW9uID0gIWNvbm5lY3Rpb24uZ2V0QXJncygpLmdldENvbm5lY3Rpb25cblxuICAgIGlmIChvd25zQ29ubmVjdGlvbikgdGhpcy5jb25maWd1cmF0aW9uLnJlZ2lzdGVyQWR2aXNvcnlMb2NrQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayhjb25uZWN0aW9uKVxuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAob3duc0Nvbm5lY3Rpb24pIHtcbiAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLnVucmVnaXN0ZXJBZHZpc29yeUxvY2tDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG4gICAgICAgIGF3YWl0IGNvbm5lY3Rpb24uY2xvc2UoKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgY29ubmVjdGlvbi5yZWxlYXNlSGVsZEFkdmlzb3J5TG9ja3MoKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGBjYWxsYmFja2AsIHJlamVjdGluZyB3aXRoIGBBZHZpc29yeUxvY2tIb2xkVGltZW91dEVycm9yYCBpZiBpdCBoYXNcbiAgICogbm90IHNldHRsZWQgd2l0aGluIGBob2xkVGltZW91dE1zYC4gVGhlIGNhbGxiYWNrIGlzIG5vdCBjYW5jZWxsZWQ7IGNhbGxlcnNcbiAgICogdXNlIGEgZGVkaWNhdGVkIGFkdmlzb3J5LWxvY2sgY29ubmVjdGlvbiBzbyB0aGUgbG9jayBjYW4gc3RpbGwgYmUgcmVsZWFzZWQuXG4gICAqXG4gICAqIFRoZSBjYWxsYmFjayByZWNlaXZlcyBhIGBUaW1lb3V0Q29udHJvbGAgZnJvbSBhd2FpdGVyeSwgZW5hYmxpbmcgY29vcGVyYXRpdmVcbiAgICogY2FuY2VsbGF0aW9uIHZpYSBgY29udHJvbC5jaGVjaygpYCwgYGNvbnRyb2wuc2lnbmFsYCwgYGNvbnRyb2wudGltZWRPdXRgLFxuICAgKiBhbmQgYGNvbnRyb2wucmVtYWluaW5nKClgLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZSAoZm9yIHRoZSBlcnJvciBtZXNzYWdlKS5cbiAgICogQHBhcmFtIHsoYXJncz86IHtjb250cm9sOiBpbXBvcnQoXCJhd2FpdGVyeS9idWlsZC90aW1lb3V0LmpzXCIpLlRpbWVvdXRDb250cm9sfSkgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayBob2xkaW5nIHRoZSBsb2NrLlxuICAgKiBAcGFyYW0ge251bWJlciB8IG51bGx9IFtob2xkVGltZW91dE1zXSAtIE1heCBob2xkIHRpbWU7IGZhbHN5IGRpc2FibGVzIHRoZSB0aW1lb3V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcnVuV2l0aEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0KG5hbWUsIGNhbGxiYWNrLCBob2xkVGltZW91dE1zKSB7XG4gICAgaWYgKCFob2xkVGltZW91dE1zIHx8IGhvbGRUaW1lb3V0TXMgPD0gMCkge1xuICAgICAgcmV0dXJuIGF3YWl0IGNhbGxiYWNrKClcbiAgICB9XG5cbiAgICBsZXQgY2FsbGJhY2tTZXR0bGVkID0gZmFsc2VcblxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGltZW91dCh7dGltZW91dDogaG9sZFRpbWVvdXRNc30sIGFzeW5jICh7Y29udHJvbH0pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2soe2NvbnRyb2x9KVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGNhbGxiYWNrU2V0dGxlZCA9IHRydWVcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKCFjYWxsYmFja1NldHRsZWQgfHwgZXJyb3IgaW5zdGFuY2VvZiBUaW1lb3V0RXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0RXJyb3IoYEFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX0gaGVsZCBsb25nZXIgdGhhbiAke2hvbGRUaW1lb3V0TXN9bXNgLCB7bmFtZX0pXG4gICAgICB9XG5cbiAgICAgIHRocm93IGVycm9yXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCB7QWR2aXNvcnlMb2NrQnVzeUVycm9yLCBBZHZpc29yeUxvY2tIb2xkVGltZW91dEVycm9yLCBBZHZpc29yeUxvY2tUaW1lb3V0RXJyb3J9XG4iXX0=
|
|
233
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2aXNvcnktbG9jay1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvYWR2aXNvcnktbG9jay1ydW5uZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sT0FBTyxFQUFFLEVBQUMsWUFBWSxFQUFDLE1BQU0sMkJBQTJCLENBQUE7QUFFL0Q7O0dBRUc7QUFDSCxNQUFNLHdCQUF5QixTQUFRLEtBQUs7SUFDMUM7Ozs7T0FJRztJQUNILFlBQVksT0FBTyxFQUFFLEVBQUMsSUFBSSxFQUFDO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNkLElBQUksQ0FBQyxJQUFJLEdBQUcsMEJBQTBCLENBQUE7UUFDdEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFDdEIsQ0FBQztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLHFCQUFzQixTQUFRLEtBQUs7SUFDdkM7Ozs7T0FJRztJQUNILFlBQVksT0FBTyxFQUFFLEVBQUMsSUFBSSxFQUFDO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNkLElBQUksQ0FBQyxJQUFJLEdBQUcsdUJBQXVCLENBQUE7UUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFDdEIsQ0FBQztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLDRCQUE2QixTQUFRLEtBQUs7SUFDOUM7Ozs7T0FJRztJQUNILFlBQVksT0FBTyxFQUFFLEVBQUMsSUFBSSxFQUFDO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNkLElBQUksQ0FBQyxJQUFJLEdBQUcsOEJBQThCLENBQUE7UUFDMUMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFDdEIsQ0FBQztDQUNGO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sa0JBQWtCO0lBQ3JDOzs7T0FHRztJQUNILFlBQVksRUFBQyxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUM7UUFDakUsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUE7UUFDbEMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGtCQUFrQixDQUFBO1FBQzVDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQTtJQUM5QyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7O09BY0c7SUFDSCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEdBQUcsRUFBRTtRQUM5QyxPQUFPLE1BQU0sSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEVBQUU7WUFDOUQsTUFBTSxRQUFRLEdBQUcsTUFBTSxVQUFVLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFBO1lBRWpFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDZCxNQUFNLElBQUksd0JBQXdCLENBQUMsdUNBQXVDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFDLElBQUksRUFBQyxDQUFDLENBQUE7WUFDM0csQ0FBQztZQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLElBQUksRUFBQyxDQUFDLENBQUE7UUFDdEcsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0gsS0FBSyxDQUFDLHNCQUFzQixDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxHQUFHLEVBQUU7UUFDcEQsT0FBTyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxFQUFFO1lBQzlELE1BQU0sUUFBUSxHQUFHLE1BQU0sVUFBVSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxDQUFBO1lBRTlELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDZCxNQUFNLElBQUkscUJBQXFCLENBQUMsaUJBQWlCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLEVBQUMsSUFBSSxFQUFDLENBQUMsQ0FBQTtZQUNsRyxDQUFDO1lBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQTtRQUN0RyxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7O09Ba0JHO0lBQ0gsS0FBSyxDQUFDLHVCQUF1QixDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxHQUFHLEVBQUU7UUFDckQsT0FBTyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxFQUFFO1lBQzlELE1BQU0sUUFBUSxHQUFHLE1BQU0sVUFBVSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxDQUFBO1lBRTlELElBQUksQ0FBQyxRQUFRO2dCQUFFLE9BQU8sRUFBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBQyxDQUFBO1lBRTVFLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUMsUUFBUSxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBO1lBRTVHLE9BQU8sRUFBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBQyxDQUFBO1FBQ2pDLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEVBQUMsUUFBUSxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFDO1FBQ2pFLElBQUksQ0FBQztZQUNILE9BQU8sTUFBTSxrQkFBa0IsQ0FBQyw4QkFBOEIsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLGFBQWEsQ0FBQyxDQUFBO1FBQy9GLENBQUM7Z0JBQVMsQ0FBQztZQUNULE1BQU0sVUFBVSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzVDLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsUUFBUTtRQUNyQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFBO1FBRXhDLElBQUksSUFBSSxDQUFDLG1CQUFtQixJQUFJLENBQUMsYUFBYSxJQUFJLGFBQWEsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3JFLE9BQU8sTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDckQsQ0FBQztRQUVELE9BQU8sTUFBTSxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQTtJQUNsRCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsS0FBSyxDQUFDLHVCQUF1QixDQUFDLFFBQVE7UUFDcEMsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQTtRQUV0RyxpRkFBaUY7UUFDakYsa0ZBQWtGO1FBQ2xGLGtGQUFrRjtRQUNsRiw4RUFBOEU7UUFDOUUsTUFBTSxjQUFjLEdBQUcsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUMsYUFBYSxDQUFBO1FBRTFELElBQUksY0FBYztZQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsOEJBQThCLENBQUMsVUFBVSxDQUFDLENBQUE7UUFFakYsSUFBSSxDQUFDO1lBQ0gsT0FBTyxNQUFNLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUNuQyxDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNuQixJQUFJLENBQUMsYUFBYSxDQUFDLGdDQUFnQyxDQUFDLFVBQVUsQ0FBQyxDQUFBO2dCQUMvRCxNQUFNLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtZQUMxQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxVQUFVLENBQUMsd0JBQXdCLEVBQUUsQ0FBQTtZQUM3QyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLGFBQWE7UUFDdkUsSUFBSSxDQUFDLGFBQWEsSUFBSSxhQUFhLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDekMsT0FBTyxNQUFNLFFBQVEsRUFBRSxDQUFBO1FBQ3pCLENBQUM7UUFFRCxJQUFJLGVBQWUsR0FBRyxLQUFLLENBQUE7UUFFM0IsSUFBSSxDQUFDO1lBQ0gsT0FBTyxNQUFNLE9BQU8sQ0FBQyxFQUFDLE9BQU8sRUFBRSxhQUFhLEVBQUMsRUFBRSxLQUFLLEVBQUUsRUFBQyxPQUFPLEVBQUMsRUFBRSxFQUFFO2dCQUNqRSxJQUFJLENBQUM7b0JBQ0gsT0FBTyxNQUFNLFFBQVEsQ0FBQyxFQUFDLE9BQU8sRUFBQyxDQUFDLENBQUE7Z0JBQ2xDLENBQUM7d0JBQVMsQ0FBQztvQkFDVCxlQUFlLEdBQUcsSUFBSSxDQUFBO2dCQUN4QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUE7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxlQUFlLElBQUksS0FBSyxZQUFZLFlBQVksRUFBRSxDQUFDO2dCQUN0RCxNQUFNLElBQUksNEJBQTRCLENBQUMsaUJBQWlCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLHFCQUFxQixhQUFhLElBQUksRUFBRSxFQUFDLElBQUksRUFBQyxDQUFDLENBQUE7WUFDN0gsQ0FBQztZQUVELE1BQU0sS0FBSyxDQUFBO1FBQ2IsQ0FBQztJQUNILENBQUM7Q0FDRjtBQUVELE9BQU8sRUFBQyxxQkFBcUIsRUFBRSw0QkFBNEIsRUFBRSx3QkFBd0IsRUFBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB0aW1lb3V0LCB7VGltZW91dEVycm9yfSBmcm9tIFwiYXdhaXRlcnkvYnVpbGQvdGltZW91dC5qc1wiXG5cbi8qKlxuICogVGhyb3duIHdoZW4gYW4gYWR2aXNvcnkgbG9jayBjb3VsZCBub3QgYmUgYWNxdWlyZWQgYmVmb3JlIGB0aW1lb3V0TXNgIGVsYXBzZWQuXG4gKi9cbmNsYXNzIEFkdmlzb3J5TG9ja1RpbWVvdXRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHBhcmFtIHt7bmFtZTogc3RyaW5nfX0gYXJncyAtIFRoZSBhZHZpc29yeSBsb2NrIG5hbWUgdGhhdCB0aW1lZCBvdXQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrVGltZW91dEVycm9yXCJcbiAgICB0aGlzLmxvY2tOYW1lID0gbmFtZVxuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gYHdpdGhBZHZpc29yeUxvY2tPckZhaWxgIGZpbmRzIHRoZSBsb2NrIGFscmVhZHkgaGVsZC5cbiAqL1xuY2xhc3MgQWR2aXNvcnlMb2NrQnVzeUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBFcnJvciBtZXNzYWdlLlxuICAgKiBAcGFyYW0ge3tuYW1lOiBzdHJpbmd9fSBhcmdzIC0gVGhlIGFkdmlzb3J5IGxvY2sgbmFtZSB0aGF0IHdhcyBhbHJlYWR5IGhlbGQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrQnVzeUVycm9yXCJcbiAgICB0aGlzLmxvY2tOYW1lID0gbmFtZVxuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gYSBjYWxsYmFjayBob2xkcyBhbiBhZHZpc29yeSBsb2NrIGxvbmdlciB0aGFuIGBob2xkVGltZW91dE1zYC5cbiAqL1xuY2xhc3MgQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHBhcmFtIHt7bmFtZTogc3RyaW5nfX0gYXJncyAtIFRoZSBhZHZpc29yeSBsb2NrIG5hbWUgd2hvc2UgaG9sZCB0aW1lZCBvdXQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvclwiXG4gICAgdGhpcy5sb2NrTmFtZSA9IG5hbWVcbiAgfVxufVxuXG4vKipcbiAqIFJ1bnMgYWR2aXNvcnkgbG9ja3Mgb24gdGhlIGNhbGxlciBjb25uZWN0aW9uIGJ5IGRlZmF1bHQsIHVzaW5nIGEgZGVkaWNhdGVkXG4gKiBsb2NrIGNvbm5lY3Rpb24gd2hlbiBgZGVkaWNhdGVkQ29ubmVjdGlvbmAgaXMgcmVxdWVzdGVkIG9yIHdoZW4gYSBwb3NpdGl2ZVxuICogaG9sZCB0aW1lb3V0IG5lZWRzIHNlcGFyYXRlIG93bmVyc2hpcC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWR2aXNvcnlMb2NrUnVubmVyIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYWR2aXNvcnktbG9jayBydW5uZXIgZm9yIG9uZSBtb2RlbCBkYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge3tjb25maWd1cmF0aW9uOiBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHQsIGNvbm5lY3Rpb25Qcm92aWRlcjogKCkgPT4gaW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwgZGF0YWJhc2VJZGVudGlmaWVyOiBzdHJpbmd9fSBhcmdzIC0gUnVubmVyIGRlcGVuZGVuY2llcy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9uLCBjb25uZWN0aW9uUHJvdmlkZXIsIGRhdGFiYXNlSWRlbnRpZmllcn0pIHtcbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uXG4gICAgdGhpcy5jb25uZWN0aW9uUHJvdmlkZXIgPSBjb25uZWN0aW9uUHJvdmlkZXJcbiAgICB0aGlzLmRhdGFiYXNlSWRlbnRpZmllciA9IGRhdGFiYXNlSWRlbnRpZmllclxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYSBjYWxsYmFjayBhZnRlciBhY3F1aXJpbmcgdGhlIGFkdmlzb3J5IGxvY2ssIHdhaXRpbmcgdXAgdG8gYHRpbWVvdXRNc2AuXG4gICAqIFdoZW4gYGRlZGljYXRlZENvbm5lY3Rpb25gIGlzIHRydWUgdGhlIGxvY2sgaXMgYWNxdWlyZWQgb24gYSBzcGF3bmVkXG4gICAqIGNvbm5lY3Rpb24gdGhhdCBpcyByZWxlYXNlZCBhZnRlciB0aGUgY2FsbGJhY2sgZmluaXNoZXMsIHdoaWxlIHRoZSBjYWxsYmFja1xuICAgKiBpdHNlbGYgc3RpbGwgcnVucyBhZ2FpbnN0IHRoZSBjYWxsZXIvbW9kZWwgY29ubmVjdGlvbi4gV2hlbiBhIGBob2xkVGltZW91dE1zYFxuICAgKiBpcyBzZXQgdGhlIGNhbGxiYWNrIHJlY2VpdmVzIGEgYFRpbWVvdXRDb250cm9sYCBmcm9tIGF3YWl0ZXJ5IGZvciBjb29wZXJhdGl2ZVxuICAgKiBjYW5jZWxsYXRpb24gKGBjb250cm9sLmNoZWNrKClgLCBgY29udHJvbC5zaWduYWxgLCBgY29udHJvbC50aW1lZE91dGAsXG4gICAqIGBjb250cm9sLnJlbWFpbmluZygpYCk7IGEgZGVkaWNhdGVkIGNvbm5lY3Rpb24gaXMgYWxzbyB1c2VkIHNvIHRpbWVvdXRcbiAgICogY2xlYW51cCBjYW4gcmVsZWFzZSB0aGUgbG9jayBldmVuIGlmIGNhbGxiYWNrIGRhdGFiYXNlIHdvcmsgaXMgc3R1Y2suXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcGFyYW0geyhhcmdzPzoge2NvbnRyb2w6IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2x9KSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIGludm9rZSB3aGlsZSB0aGUgbG9jayBpcyBoZWxkLlxuICAgKiBAcGFyYW0ge3t0aW1lb3V0TXM/OiBudW1iZXIgfCBudWxsLCBob2xkVGltZW91dE1zPzogbnVtYmVyIHwgbnVsbCwgZGVkaWNhdGVkQ29ubmVjdGlvbj86IGJvb2xlYW59fSBbYXJnc10gLSBMb2NrIGFuZCBob2xkIHRpbWVvdXQgb3B0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgd2l0aEFkdmlzb3J5TG9jayhuYW1lLCBjYWxsYmFjaywgYXJncyA9IHt9KSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMud2l0aExvY2tDb25uZWN0aW9uKGFyZ3MsIGFzeW5jIChjb25uZWN0aW9uKSA9PiB7XG4gICAgICBjb25zdCBhY3F1aXJlZCA9IGF3YWl0IGNvbm5lY3Rpb24uYWNxdWlyZUFkdmlzb3J5TG9jayhuYW1lLCBhcmdzKVxuXG4gICAgICBpZiAoIWFjcXVpcmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBBZHZpc29yeUxvY2tUaW1lb3V0RXJyb3IoYFRpbWVkIG91dCB3YWl0aW5nIGZvciBhZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9YCwge25hbWV9KVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5Mb2NrZWRDYWxsYmFjayh7Y2FsbGJhY2ssIGNvbm5lY3Rpb24sIGhvbGRUaW1lb3V0TXM6IGFyZ3MuaG9sZFRpbWVvdXRNcywgbmFtZX0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGEgY2FsbGJhY2sgb25seSBpZiB0aGUgYWR2aXNvcnkgbG9jayBjYW4gYmUgYWNxdWlyZWQgaW1tZWRpYXRlbHkuXG4gICAqIFdoZW4gYGRlZGljYXRlZENvbm5lY3Rpb25gIGlzIHRydWUgdGhlIGxvY2sgaXMgYWNxdWlyZWQgb24gYSBzcGF3bmVkXG4gICAqIGNvbm5lY3Rpb24gdGhhdCBpcyByZWxlYXNlZCBhZnRlciB0aGUgY2FsbGJhY2sgZmluaXNoZXMsIHdoaWxlIHRoZSBjYWxsYmFja1xuICAgKiBpdHNlbGYgc3RpbGwgcnVucyBhZ2FpbnN0IHRoZSBjYWxsZXIvbW9kZWwgY29ubmVjdGlvbi4gV2hlbiBhIGBob2xkVGltZW91dE1zYFxuICAgKiBpcyBzZXQgdGhlIGNhbGxiYWNrIHJlY2VpdmVzIGEgYFRpbWVvdXRDb250cm9sYCBmcm9tIGF3YWl0ZXJ5IGZvciBjb29wZXJhdGl2ZVxuICAgKiBjYW5jZWxsYXRpb24uXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcGFyYW0geyhhcmdzPzoge2NvbnRyb2w6IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2x9KSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIGludm9rZSB3aGlsZSB0aGUgbG9jayBpcyBoZWxkLlxuICAgKiBAcGFyYW0ge3tob2xkVGltZW91dE1zPzogbnVtYmVyIHwgbnVsbCwgZGVkaWNhdGVkQ29ubmVjdGlvbj86IGJvb2xlYW59fSBbYXJnc10gLSBIb2xkIHRpbWVvdXQgb3B0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgd2l0aEFkdmlzb3J5TG9ja09yRmFpbChuYW1lLCBjYWxsYmFjaywgYXJncyA9IHt9KSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMud2l0aExvY2tDb25uZWN0aW9uKGFyZ3MsIGFzeW5jIChjb25uZWN0aW9uKSA9PiB7XG4gICAgICBjb25zdCBhY3F1aXJlZCA9IGF3YWl0IGNvbm5lY3Rpb24udHJ5QWNxdWlyZUFkdmlzb3J5TG9jayhuYW1lKVxuXG4gICAgICBpZiAoIWFjcXVpcmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBBZHZpc29yeUxvY2tCdXN5RXJyb3IoYEFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX0gaXMgYWxyZWFkeSBoZWxkYCwge25hbWV9KVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5Mb2NrZWRDYWxsYmFjayh7Y2FsbGJhY2ssIGNvbm5lY3Rpb24sIGhvbGRUaW1lb3V0TXM6IGFyZ3MuaG9sZFRpbWVvdXRNcywgbmFtZX0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGEgY2FsbGJhY2sgaWYgdGhlIGFkdmlzb3J5IGxvY2sgY2FuIGJlIGFjcXVpcmVkIHdpdGhvdXQgd2FpdGluZztcbiAgICogb3RoZXJ3aXNlIHJldHVybnMgYSBge2FjcXVpcmVkOiBmYWxzZX1gIGRlZmVyIHJlc3VsdCBpbnN0ZWFkIG9mIHRocm93aW5nLlxuICAgKlxuICAgKiBUaGlzIGlzIHRoZSBub24tdGhyb3dpbmcgY291bnRlcnBhcnQgb2YgYHdpdGhBZHZpc29yeUxvY2tPckZhaWxgIGZvciBob3RcbiAgICogcGF0aHM6IFwiaG9sZGVyIGJ1c3ksIGRlZmVyIG1lXCIgaXMgYSBmaXJzdC1jbGFzcyBvdXRjb21lLCBzbyBhIGNvbnRlbmRlZFxuICAgKiBsb2NrIHByb2R1Y2VzIHplcm8gZXhjZXB0aW9uIHRyYWZmaWMgYW5kIOKAlCBiZWNhdXNlIHRoZSBwcm9iZSBpcyBhIHNpbmdsZVxuICAgKiBpbW1lZGlhdGUgdHJ5LWFjcXVpcmUg4oCUIHplcm8gcGlubmVkIGNvbm5lY3Rpb25zLiBDYWxsZXJzIHJlc2NoZWR1bGUgdmlhXG4gICAqIHRoZWlyIG93biBldmVudC1kcml2ZW4gcmV0cnkgbWFjaGluZXJ5LiBUaGUgcmVzdWx0IGZvcm0gaXMgaWRlbnRpY2FsXG4gICAqIGFjcm9zcyB0aWVyczogdGhlIGRyaXZlcidzIGB0cnlBY3F1aXJlQWR2aXNvcnlMb2NrYCBtYXBzIHBlci10aWVyIChNeVNRTFxuICAgKiBgR0VUX0xPQ0sobmFtZSwgMClgLCBQb3N0Z3JlU1FMIGBwZ190cnlfYWR2aXNvcnlfbG9ja2AsIFNRTCBTZXJ2ZXJcbiAgICogYHNwX2dldGFwcGxvY2sgQExvY2tUaW1lb3V0ID0gMGAsIFNRTGl0ZSBwcm9jZXNzLWxvY2FsIHF1ZXVlLCBTUUxpdGUgTm9kZVxuICAgKiBmaWxlIGxvY2spLCBzbyBhIGNhbGxlciBuZXZlciBicmFuY2hlcyBvbiB0aGUgYmFja2VuZC5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NrIG5hbWUuXG4gICAqIEBwYXJhbSB7KGFyZ3M/OiB7Y29udHJvbDogaW1wb3J0KFwiYXdhaXRlcnkvYnVpbGQvdGltZW91dC5qc1wiKS5UaW1lb3V0Q29udHJvbH0pID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gaW52b2tlIHdoaWxlIHRoZSBsb2NrIGlzIGhlbGQuXG4gICAqIEBwYXJhbSB7e2hvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsLCBkZWRpY2F0ZWRDb25uZWN0aW9uPzogYm9vbGVhbn19IFthcmdzXSAtIEhvbGQgdGltZW91dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7YWNxdWlyZWQ6IHRydWUsIHJlc3VsdDogVH0gfCB7YWNxdWlyZWQ6IGZhbHNlLCByZWFzb246IFwiY29udGVuZGVkXCIsIGxvY2tOYW1lOiBzdHJpbmd9Pn0gLSBFaXRoZXIgdGhlIGhlbGQtY2FsbGJhY2sgcmVzdWx0IG9yIHRoZSBkZWZlciBvdXRjb21lLlxuICAgKi9cbiAgYXN5bmMgd2l0aEFkdmlzb3J5TG9ja09yRGVmZXIobmFtZSwgY2FsbGJhY2ssIGFyZ3MgPSB7fSkge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhMb2NrQ29ubmVjdGlvbihhcmdzLCBhc3luYyAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgY29uc3QgYWNxdWlyZWQgPSBhd2FpdCBjb25uZWN0aW9uLnRyeUFjcXVpcmVBZHZpc29yeUxvY2sobmFtZSlcblxuICAgICAgaWYgKCFhY3F1aXJlZCkgcmV0dXJuIHthY3F1aXJlZDogZmFsc2UsIHJlYXNvbjogXCJjb250ZW5kZWRcIiwgbG9ja05hbWU6IG5hbWV9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucnVuTG9ja2VkQ2FsbGJhY2soe2NhbGxiYWNrLCBjb25uZWN0aW9uLCBob2xkVGltZW91dE1zOiBhcmdzLmhvbGRUaW1lb3V0TXMsIG5hbWV9KVxuXG4gICAgICByZXR1cm4ge2FjcXVpcmVkOiB0cnVlLCByZXN1bHR9XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRoZSBsb2NrIGhvbGRlciBjYWxsYmFjayBhbmQgcmVsZWFzZXMgdGhlIGxvY2sgZnJvbSBpdHMgb3duaW5nIGNvbm5lY3Rpb24uXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7e2NhbGxiYWNrOiAoYXJncz86IHtjb250cm9sOiBpbXBvcnQoXCJhd2FpdGVyeS9idWlsZC90aW1lb3V0LmpzXCIpLlRpbWVvdXRDb250cm9sfSkgPT4gUHJvbWlzZTxUPiwgY29ubmVjdGlvbjogaW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwgaG9sZFRpbWVvdXRNcz86IG51bWJlciB8IG51bGwsIG5hbWU6IHN0cmluZ319IGFyZ3MgLSBMb2NrZWQgY2FsbGJhY2sgYXJncy5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgcnVuTG9ja2VkQ2FsbGJhY2soe2NhbGxiYWNrLCBjb25uZWN0aW9uLCBob2xkVGltZW91dE1zLCBuYW1lfSkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgQWR2aXNvcnlMb2NrUnVubmVyLnJ1bldpdGhBZHZpc29yeUxvY2tIb2xkVGltZW91dChuYW1lLCBjYWxsYmFjaywgaG9sZFRpbWVvdXRNcylcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5yZWxlYXNlQWR2aXNvcnlMb2NrKG5hbWUpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbG9jayB3b3JrIG9uIHRoZSBjYWxsZXIgY29ubmVjdGlvbiB1bmxlc3MgYGRlZGljYXRlZENvbm5lY3Rpb25gIGlzXG4gICAqIHJlcXVlc3RlZCBvciBhIHBvc2l0aXZlIGhvbGQgdGltZW91dCBuZWVkcyBpdHMgb3duIGxvY2sgY29ubmVjdGlvbi5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHt7ZGVkaWNhdGVkQ29ubmVjdGlvbj86IGJvb2xlYW4sIGhvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsfX0gYXJncyAtIExvY2sgY29ubmVjdGlvbiBvcHRpb25zLlxuICAgKiBAcGFyYW0geyhjb25uZWN0aW9uOiBpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0KSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHJlY2VpdmluZyB0aGUgY29ubmVjdGlvbiB0aGF0IG93bnMgdGhlIGFkdmlzb3J5IGxvY2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHdpdGhMb2NrQ29ubmVjdGlvbihhcmdzLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IGhvbGRUaW1lb3V0TXMgPSBhcmdzLmhvbGRUaW1lb3V0TXNcblxuICAgIGlmIChhcmdzLmRlZGljYXRlZENvbm5lY3Rpb24gfHwgKGhvbGRUaW1lb3V0TXMgJiYgaG9sZFRpbWVvdXRNcyA+IDApKSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy53aXRoRGVkaWNhdGVkQ29ubmVjdGlvbihjYWxsYmFjaylcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2sodGhpcy5jb25uZWN0aW9uUHJvdmlkZXIoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGF3bnMgYSBkZWRpY2F0ZWQgbG9jayBjb25uZWN0aW9uIGFuZCBjbG9zZXMgaXQgYWZ0ZXIgbG9jayB3b3JrIGNvbXBsZXRlc1xuICAgKiB3aGVuIHRoZSBzcGF3bmVkIGRyaXZlciBvd25zIHRoZSB1bmRlcmx5aW5nIHBoeXNpY2FsIGNvbm5lY3Rpb24uXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7KGNvbm5lY3Rpb246IGltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdGhhdCByZWNlaXZlcyB0aGUgZGVkaWNhdGVkIGxvY2sgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgd2l0aERlZGljYXRlZENvbm5lY3Rpb24oY2FsbGJhY2spIHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmdldERhdGFiYXNlUG9vbCh0aGlzLmRhdGFiYXNlSWRlbnRpZmllcikuc3Bhd25Db25uZWN0aW9uKClcblxuICAgIC8vIFRoZSBzcGF3bmVkIGRyaXZlciBvd25zIGl0cyBwaHlzaWNhbCBjb25uZWN0aW9uIHVubGVzcyBpdCBib3Jyb3dzIGEgc2hhcmVkIG9uZVxuICAgIC8vIHZpYSBgZ2V0Q29ubmVjdGlvbmAuIEFuIG93bmVkIGNvbm5lY3Rpb24gbGl2ZXMgb3V0c2lkZSB0aGUgcG9vbHMnIHRyYWNrZWQgc2V0cyxcbiAgICAvLyBzbyByZWdpc3RlciBpdCB3aGlsZSB0aGUgbG9jayBpcyBoZWxkOiBhIHNodXRkb3duIHRoZW4gY2xvc2VzIGl0IChyZWxlYXNpbmcgdGhlXG4gICAgLy8gbG9jaykgaW5zdGVhZCBvZiBvcnBoYW5pbmcgYSBoYWxmLW9wZW4gc2Vzc2lvbiB1bnRpbCB0aGUgREIgYHdhaXRfdGltZW91dGAuXG4gICAgY29uc3Qgb3duc0Nvbm5lY3Rpb24gPSAhY29ubmVjdGlvbi5nZXRBcmdzKCkuZ2V0Q29ubmVjdGlvblxuXG4gICAgaWYgKG93bnNDb25uZWN0aW9uKSB0aGlzLmNvbmZpZ3VyYXRpb24ucmVnaXN0ZXJBZHZpc29yeUxvY2tDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGNhbGxiYWNrKGNvbm5lY3Rpb24pXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmIChvd25zQ29ubmVjdGlvbikge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24udW5yZWdpc3RlckFkdmlzb3J5TG9ja0Nvbm5lY3Rpb24oY29ubmVjdGlvbilcbiAgICAgICAgYXdhaXQgY29ubmVjdGlvbi5jbG9zZSgpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCBjb25uZWN0aW9uLnJlbGVhc2VIZWxkQWR2aXNvcnlMb2NrcygpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYGNhbGxiYWNrYCwgcmVqZWN0aW5nIHdpdGggYEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0RXJyb3JgIGlmIGl0IGhhc1xuICAgKiBub3Qgc2V0dGxlZCB3aXRoaW4gYGhvbGRUaW1lb3V0TXNgLiBUaGUgY2FsbGJhY2sgaXMgbm90IGNhbmNlbGxlZDsgY2FsbGVyc1xuICAgKiB1c2UgYSBkZWRpY2F0ZWQgYWR2aXNvcnktbG9jayBjb25uZWN0aW9uIHNvIHRoZSBsb2NrIGNhbiBzdGlsbCBiZSByZWxlYXNlZC5cbiAgICpcbiAgICogVGhlIGNhbGxiYWNrIHJlY2VpdmVzIGEgYFRpbWVvdXRDb250cm9sYCBmcm9tIGF3YWl0ZXJ5LCBlbmFibGluZyBjb29wZXJhdGl2ZVxuICAgKiBjYW5jZWxsYXRpb24gdmlhIGBjb250cm9sLmNoZWNrKClgLCBgY29udHJvbC5zaWduYWxgLCBgY29udHJvbC50aW1lZE91dGAsXG4gICAqIGFuZCBgY29udHJvbC5yZW1haW5pbmcoKWAuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lIChmb3IgdGhlIGVycm9yIG1lc3NhZ2UpLlxuICAgKiBAcGFyYW0geyhhcmdzPzoge2NvbnRyb2w6IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2x9KSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIGhvbGRpbmcgdGhlIGxvY2suXG4gICAqIEBwYXJhbSB7bnVtYmVyIHwgbnVsbH0gW2hvbGRUaW1lb3V0TXNdIC0gTWF4IGhvbGQgdGltZTsgZmFsc3kgZGlzYWJsZXMgdGhlIHRpbWVvdXQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBydW5XaXRoQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXQobmFtZSwgY2FsbGJhY2ssIGhvbGRUaW1lb3V0TXMpIHtcbiAgICBpZiAoIWhvbGRUaW1lb3V0TXMgfHwgaG9sZFRpbWVvdXRNcyA8PSAwKSB7XG4gICAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2soKVxuICAgIH1cblxuICAgIGxldCBjYWxsYmFja1NldHRsZWQgPSBmYWxzZVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aW1lb3V0KHt0aW1lb3V0OiBob2xkVGltZW91dE1zfSwgYXN5bmMgKHtjb250cm9sfSkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayh7Y29udHJvbH0pXG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgY2FsbGJhY2tTZXR0bGVkID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoIWNhbGxiYWNrU2V0dGxlZCB8fCBlcnJvciBpbnN0YW5jZW9mIFRpbWVvdXRFcnJvcikge1xuICAgICAgICB0aHJvdyBuZXcgQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvcihgQWR2aXNvcnkgbG9jayAke0pTT04uc3RyaW5naWZ5KG5hbWUpfSBoZWxkIGxvbmdlciB0aGFuICR7aG9sZFRpbWVvdXRNc31tc2AsIHtuYW1lfSlcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHtBZHZpc29yeUxvY2tCdXN5RXJyb3IsIEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0RXJyb3IsIEFkdmlzb3J5TG9ja1RpbWVvdXRFcnJvcn1cbiJdfQ==
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
export type AdvisoryLockTelemetryReport = {
|
|
2
|
+
/**
|
|
3
|
+
* - Which event fired.
|
|
4
|
+
*/
|
|
5
|
+
event: "advisory-lock-slow-acquire" | "advisory-lock-acquire-timeout" | "advisory-lock-slow-hold";
|
|
6
|
+
/**
|
|
7
|
+
* - The contended advisory-lock name.
|
|
8
|
+
*/
|
|
9
|
+
lockName: string;
|
|
10
|
+
/**
|
|
11
|
+
* - Tier that served (or refused) the acquisition: `driver-native`, `process-local`, or `file`.
|
|
12
|
+
*/
|
|
13
|
+
backendTier: string;
|
|
14
|
+
/**
|
|
15
|
+
* - Measured duration of the acquire wait (or the hold).
|
|
16
|
+
*/
|
|
17
|
+
durationMs: number;
|
|
18
|
+
/**
|
|
19
|
+
* - For acquire events: whether the wait eventually acquired the lock. Null for hold reports.
|
|
20
|
+
*/
|
|
21
|
+
outcome: "acquired" | "timeout" | null;
|
|
22
|
+
/**
|
|
23
|
+
* - The effective acquire bound for acquire events. Null for hold reports or an unbounded wait.
|
|
24
|
+
*/
|
|
25
|
+
timeoutMs: number | null;
|
|
26
|
+
/**
|
|
27
|
+
* - Process-local holder attribution when the tier can name its local holder.
|
|
28
|
+
*/
|
|
29
|
+
holderId: string | null;
|
|
30
|
+
/**
|
|
31
|
+
* - Driver-native holder attribution captured at the event moment (MariaDB `IS_USED_LOCK` connection id, PostgreSQL pid, SQL Server session id, SQLite file `pid@hostname`).
|
|
32
|
+
*/
|
|
33
|
+
holderConnectionId: string | null;
|
|
34
|
+
/**
|
|
35
|
+
* - Set when the best-effort holder lookup itself failed; the lookup never affects the acquisition.
|
|
36
|
+
*/
|
|
37
|
+
holderLookupError: string | null;
|
|
38
|
+
};
|
|
39
|
+
export type AdvisoryLockTelemetryThresholds = {
|
|
40
|
+
/**
|
|
41
|
+
* - Report an acquire wait slower than this; `null` disables slow-acquire reports.
|
|
42
|
+
*/
|
|
43
|
+
slowAcquireMs: number | null;
|
|
44
|
+
/**
|
|
45
|
+
* - Report a hold longer than this at release; `null` disables hold reports.
|
|
46
|
+
*/
|
|
47
|
+
slowHoldMs: number | null;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Event-driven advisory-lock duration telemetry (STC-261, parent epic STC-209).
|
|
51
|
+
*
|
|
52
|
+
* A lock convoy is only fixable when it is *attributable*: which lock name was
|
|
53
|
+
* contended, on which backend tier, for how long, and who held it. These reports
|
|
54
|
+
* fire on the acquisition/release events themselves — never from a periodic
|
|
55
|
+
* scanner — so a contended lock in production surfaces on the framework-error
|
|
56
|
+
* channel with the holder identity available on that tier at that moment,
|
|
57
|
+
* without SSH forensics.
|
|
58
|
+
*
|
|
59
|
+
* Three events, each with its own threshold (all configurable per database via
|
|
60
|
+
* `advisoryLockTelemetry`, see `docs/advisory-locks.md`):
|
|
61
|
+
*
|
|
62
|
+
* - `advisory-lock-slow-acquire` — an acquire wait completed slower than
|
|
63
|
+
* `slowAcquireMs` (default 5000), including the eventual outcome (`acquired`
|
|
64
|
+
* or `timeout`).
|
|
65
|
+
* - `advisory-lock-acquire-timeout` — a wait exceeded its timeout. The report
|
|
66
|
+
* carries the holder identity available on the tier at that moment: the
|
|
67
|
+
* driver-native tiers attribute the holder connection (MariaDB
|
|
68
|
+
* `IS_USED_LOCK`, PostgreSQL `pg_locks` joined to `pg_stat_activity`, SQL
|
|
69
|
+
* Server `sys.dm_tran_locks` request session, SQLite Node file tier
|
|
70
|
+
* `owner.json` pid/hostname); the process-local tier reports the owning
|
|
71
|
+
* driver's `holderId`.
|
|
72
|
+
* - `advisory-lock-slow-hold` — a hold lasted longer than `slowHoldMs`
|
|
73
|
+
* (default 60000), emitted at release.
|
|
74
|
+
*
|
|
75
|
+
* Reports are emitted on `configuration.getErrorEvents()` as `framework-error`
|
|
76
|
+
* (plus the matching `all-error`) with `{context: "advisory-lock-telemetry",
|
|
77
|
+
* event, lockName, backendTier, ...}` payloads, matching the repo's "never
|
|
78
|
+
* swallow" rule so process-level bug reporters capture them.
|
|
79
|
+
*
|
|
80
|
+
* Holder lookups are strictly best-effort *after* the acquisition already
|
|
81
|
+
* settled: a failed lookup never changes the acquisition outcome and never
|
|
82
|
+
* throws to the caller.
|
|
83
|
+
*/
|
|
84
|
+
/**
|
|
85
|
+
* One advisory-lock telemetry report.
|
|
86
|
+
* @typedef {object} AdvisoryLockTelemetryReport
|
|
87
|
+
* @property {"advisory-lock-slow-acquire" | "advisory-lock-acquire-timeout" | "advisory-lock-slow-hold"} event - Which event fired.
|
|
88
|
+
* @property {string} lockName - The contended advisory-lock name.
|
|
89
|
+
* @property {string} backendTier - Tier that served (or refused) the acquisition: `driver-native`, `process-local`, or `file`.
|
|
90
|
+
* @property {number} durationMs - Measured duration of the acquire wait (or the hold).
|
|
91
|
+
* @property {"acquired" | "timeout" | null} outcome - For acquire events: whether the wait eventually acquired the lock. Null for hold reports.
|
|
92
|
+
* @property {number | null} timeoutMs - The effective acquire bound for acquire events. Null for hold reports or an unbounded wait.
|
|
93
|
+
* @property {string | null} holderId - Process-local holder attribution when the tier can name its local holder.
|
|
94
|
+
* @property {string | null} holderConnectionId - Driver-native holder attribution captured at the event moment (MariaDB `IS_USED_LOCK` connection id, PostgreSQL pid, SQL Server session id, SQLite file `pid@hostname`).
|
|
95
|
+
* @property {string | null} holderLookupError - Set when the best-effort holder lookup itself failed; the lookup never affects the acquisition.
|
|
96
|
+
*/
|
|
97
|
+
/**
|
|
98
|
+
* Resolved per-database telemetry thresholds.
|
|
99
|
+
* @typedef {object} AdvisoryLockTelemetryThresholds
|
|
100
|
+
* @property {number | null} slowAcquireMs - Report an acquire wait slower than this; `null` disables slow-acquire reports.
|
|
101
|
+
* @property {number | null} slowHoldMs - Report a hold longer than this at release; `null` disables hold reports.
|
|
102
|
+
*/
|
|
103
|
+
/** Framework default: report an acquire wait that completed slower than this. */
|
|
104
|
+
export declare const DEFAULT_ADVISORY_LOCK_SLOW_ACQUIRE_MS = 5000;
|
|
105
|
+
/** Framework default: report a hold that outlives this at release. */
|
|
106
|
+
export declare const DEFAULT_ADVISORY_LOCK_SLOW_HOLD_MS: number;
|
|
107
|
+
/**
|
|
108
|
+
* Resolve the telemetry thresholds for one database configuration.
|
|
109
|
+
* An explicit per-database `advisoryLockTelemetry` value wins; `null` opts out
|
|
110
|
+
* of that report; only when neither is configured does the framework default
|
|
111
|
+
* apply.
|
|
112
|
+
* @param {import("../configuration-types.js").DatabaseConfigurationType} args - Database configuration args.
|
|
113
|
+
* @returns {AdvisoryLockTelemetryThresholds} - Resolved thresholds.
|
|
114
|
+
*/
|
|
115
|
+
export declare function advisoryLockTelemetryThresholds(args: import("../configuration-types.js").DatabaseConfigurationType): AdvisoryLockTelemetryThresholds;
|
|
116
|
+
/**
|
|
117
|
+
* Emit one telemetry report on the framework-error channel.
|
|
118
|
+
*
|
|
119
|
+
* Mirrors the repo's framework-error emission shape (see `configuration.js`
|
|
120
|
+
* `_reportBeaconError`): when no listener is attached to `framework-error` or
|
|
121
|
+
* `all-error`, a one-line summary goes to `stderr` so a convoy is never
|
|
122
|
+
* completely silent. A listener failure can never break lock handling, so
|
|
123
|
+
* emissions are guarded.
|
|
124
|
+
* @param {import("../configuration.js").default} configuration - Configuration instance owning the error channel.
|
|
125
|
+
* @param {AdvisoryLockTelemetryReport} report - The report payload.
|
|
126
|
+
* @returns {void} - No return value.
|
|
127
|
+
*/
|
|
128
|
+
export declare function emitAdvisoryLockTelemetryReport(configuration: import("../configuration.js").default, report: AdvisoryLockTelemetryReport): void;
|
|
129
|
+
//# sourceMappingURL=advisory-lock-telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advisory-lock-telemetry.d.ts","sourceRoot":"","sources":["../../../src/database/advisory-lock-telemetry.js"],"names":[],"mappings":"AAwCG,YAAkB,2BAA2B,GAC7C;;;;IAAuG,KAAK,EAAjG,4BAA4B,GAAG,+BAA+B,GAAG,yBAAyB,CACrG;;;;IAAmB,QAAQ,EAAhB,MAAM,CACjB;;;;IAAmB,WAAW,EAAnB,MAAM,CACjB;;;;IAAmB,UAAU,EAAlB,MAAM,CACjB;;;;IAA0C,OAAO,EAAtC,UAAU,GAAG,SAAS,GAAG,IAAI,CACxC;;;;IAA0B,SAAS,EAAxB,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,QAAQ,EAAvB,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,kBAAkB,EAAjC,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,iBAAiB,EAAhC,MAAM,GAAG,IAAI,CAC1B;CAAA,CAAA;AAIE,YAAkB,+BAA+B,GACjD;;;;IAA0B,aAAa,EAA5B,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,UAAU,EAAzB,MAAM,GAAG,IAAI,CAC1B;CAAA,CAAA;AAvDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;;;;;;;;;GAYG;AAEH;;;;;GAKG;AAEH,iFAAiF;AACjF,eAAO,MAAM,qCAAqC,OAAO,CAAA;AAEzD,sEAAsE;AACtE,eAAO,MAAM,kCAAkC,QAAY,CAAA;AAE3D;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAHzC,OAAO,2BAA2B,EAAE,yBAGK,GAFvC,+BAA+B,CAiB3C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,+BAA+B,CAAC,aAAa,EAJlD,OAAO,qBAAqB,EAAE,OAIoB,EAAE,MAAM,EAH1D,2BAG0D,GAFxD,IAAI,CA4BhB"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/**
|
|
3
|
+
* Event-driven advisory-lock duration telemetry (STC-261, parent epic STC-209).
|
|
4
|
+
*
|
|
5
|
+
* A lock convoy is only fixable when it is *attributable*: which lock name was
|
|
6
|
+
* contended, on which backend tier, for how long, and who held it. These reports
|
|
7
|
+
* fire on the acquisition/release events themselves — never from a periodic
|
|
8
|
+
* scanner — so a contended lock in production surfaces on the framework-error
|
|
9
|
+
* channel with the holder identity available on that tier at that moment,
|
|
10
|
+
* without SSH forensics.
|
|
11
|
+
*
|
|
12
|
+
* Three events, each with its own threshold (all configurable per database via
|
|
13
|
+
* `advisoryLockTelemetry`, see `docs/advisory-locks.md`):
|
|
14
|
+
*
|
|
15
|
+
* - `advisory-lock-slow-acquire` — an acquire wait completed slower than
|
|
16
|
+
* `slowAcquireMs` (default 5000), including the eventual outcome (`acquired`
|
|
17
|
+
* or `timeout`).
|
|
18
|
+
* - `advisory-lock-acquire-timeout` — a wait exceeded its timeout. The report
|
|
19
|
+
* carries the holder identity available on the tier at that moment: the
|
|
20
|
+
* driver-native tiers attribute the holder connection (MariaDB
|
|
21
|
+
* `IS_USED_LOCK`, PostgreSQL `pg_locks` joined to `pg_stat_activity`, SQL
|
|
22
|
+
* Server `sys.dm_tran_locks` request session, SQLite Node file tier
|
|
23
|
+
* `owner.json` pid/hostname); the process-local tier reports the owning
|
|
24
|
+
* driver's `holderId`.
|
|
25
|
+
* - `advisory-lock-slow-hold` — a hold lasted longer than `slowHoldMs`
|
|
26
|
+
* (default 60000), emitted at release.
|
|
27
|
+
*
|
|
28
|
+
* Reports are emitted on `configuration.getErrorEvents()` as `framework-error`
|
|
29
|
+
* (plus the matching `all-error`) with `{context: "advisory-lock-telemetry",
|
|
30
|
+
* event, lockName, backendTier, ...}` payloads, matching the repo's "never
|
|
31
|
+
* swallow" rule so process-level bug reporters capture them.
|
|
32
|
+
*
|
|
33
|
+
* Holder lookups are strictly best-effort *after* the acquisition already
|
|
34
|
+
* settled: a failed lookup never changes the acquisition outcome and never
|
|
35
|
+
* throws to the caller.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* One advisory-lock telemetry report.
|
|
39
|
+
* @typedef {object} AdvisoryLockTelemetryReport
|
|
40
|
+
* @property {"advisory-lock-slow-acquire" | "advisory-lock-acquire-timeout" | "advisory-lock-slow-hold"} event - Which event fired.
|
|
41
|
+
* @property {string} lockName - The contended advisory-lock name.
|
|
42
|
+
* @property {string} backendTier - Tier that served (or refused) the acquisition: `driver-native`, `process-local`, or `file`.
|
|
43
|
+
* @property {number} durationMs - Measured duration of the acquire wait (or the hold).
|
|
44
|
+
* @property {"acquired" | "timeout" | null} outcome - For acquire events: whether the wait eventually acquired the lock. Null for hold reports.
|
|
45
|
+
* @property {number | null} timeoutMs - The effective acquire bound for acquire events. Null for hold reports or an unbounded wait.
|
|
46
|
+
* @property {string | null} holderId - Process-local holder attribution when the tier can name its local holder.
|
|
47
|
+
* @property {string | null} holderConnectionId - Driver-native holder attribution captured at the event moment (MariaDB `IS_USED_LOCK` connection id, PostgreSQL pid, SQL Server session id, SQLite file `pid@hostname`).
|
|
48
|
+
* @property {string | null} holderLookupError - Set when the best-effort holder lookup itself failed; the lookup never affects the acquisition.
|
|
49
|
+
*/
|
|
50
|
+
/**
|
|
51
|
+
* Resolved per-database telemetry thresholds.
|
|
52
|
+
* @typedef {object} AdvisoryLockTelemetryThresholds
|
|
53
|
+
* @property {number | null} slowAcquireMs - Report an acquire wait slower than this; `null` disables slow-acquire reports.
|
|
54
|
+
* @property {number | null} slowHoldMs - Report a hold longer than this at release; `null` disables hold reports.
|
|
55
|
+
*/
|
|
56
|
+
/** Framework default: report an acquire wait that completed slower than this. */
|
|
57
|
+
export const DEFAULT_ADVISORY_LOCK_SLOW_ACQUIRE_MS = 5000;
|
|
58
|
+
/** Framework default: report a hold that outlives this at release. */
|
|
59
|
+
export const DEFAULT_ADVISORY_LOCK_SLOW_HOLD_MS = 60 * 1000;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve the telemetry thresholds for one database configuration.
|
|
62
|
+
* An explicit per-database `advisoryLockTelemetry` value wins; `null` opts out
|
|
63
|
+
* of that report; only when neither is configured does the framework default
|
|
64
|
+
* apply.
|
|
65
|
+
* @param {import("../configuration-types.js").DatabaseConfigurationType} args - Database configuration args.
|
|
66
|
+
* @returns {AdvisoryLockTelemetryThresholds} - Resolved thresholds.
|
|
67
|
+
*/
|
|
68
|
+
export function advisoryLockTelemetryThresholds(args) {
|
|
69
|
+
const configured = args?.advisoryLockTelemetry;
|
|
70
|
+
/** @type {AdvisoryLockTelemetryThresholds} */
|
|
71
|
+
const thresholds = {
|
|
72
|
+
slowAcquireMs: DEFAULT_ADVISORY_LOCK_SLOW_ACQUIRE_MS,
|
|
73
|
+
slowHoldMs: DEFAULT_ADVISORY_LOCK_SLOW_HOLD_MS
|
|
74
|
+
};
|
|
75
|
+
if (configured?.slowAcquireMs === null)
|
|
76
|
+
thresholds.slowAcquireMs = null;
|
|
77
|
+
else if (typeof configured?.slowAcquireMs === "number" && configured.slowAcquireMs >= 0)
|
|
78
|
+
thresholds.slowAcquireMs = configured.slowAcquireMs;
|
|
79
|
+
if (configured?.slowHoldMs === null)
|
|
80
|
+
thresholds.slowHoldMs = null;
|
|
81
|
+
else if (typeof configured?.slowHoldMs === "number" && configured.slowHoldMs >= 0)
|
|
82
|
+
thresholds.slowHoldMs = configured.slowHoldMs;
|
|
83
|
+
return thresholds;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Emit one telemetry report on the framework-error channel.
|
|
87
|
+
*
|
|
88
|
+
* Mirrors the repo's framework-error emission shape (see `configuration.js`
|
|
89
|
+
* `_reportBeaconError`): when no listener is attached to `framework-error` or
|
|
90
|
+
* `all-error`, a one-line summary goes to `stderr` so a convoy is never
|
|
91
|
+
* completely silent. A listener failure can never break lock handling, so
|
|
92
|
+
* emissions are guarded.
|
|
93
|
+
* @param {import("../configuration.js").default} configuration - Configuration instance owning the error channel.
|
|
94
|
+
* @param {AdvisoryLockTelemetryReport} report - The report payload.
|
|
95
|
+
* @returns {void} - No return value.
|
|
96
|
+
*/
|
|
97
|
+
export function emitAdvisoryLockTelemetryReport(configuration, report) {
|
|
98
|
+
/** @type {import("eventemitter3").EventEmitter | undefined} */
|
|
99
|
+
let errorEvents;
|
|
100
|
+
try {
|
|
101
|
+
errorEvents = configuration?.getErrorEvents();
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return; // No configuration to report through — never break lock handling.
|
|
105
|
+
}
|
|
106
|
+
if (!errorEvents)
|
|
107
|
+
return;
|
|
108
|
+
const hasListener = errorEvents.listenerCount("framework-error") > 0
|
|
109
|
+
|| errorEvents.listenerCount("all-error") > 0;
|
|
110
|
+
const payload = { context: "advisory-lock-telemetry", ...report };
|
|
111
|
+
try {
|
|
112
|
+
errorEvents.emit("framework-error", payload);
|
|
113
|
+
errorEvents.emit("all-error", { ...payload, errorType: "framework-error" });
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// A broken listener must never surface as a lock failure.
|
|
117
|
+
}
|
|
118
|
+
if (!hasListener) {
|
|
119
|
+
console.error(`[velocious advisory-lock-telemetry ${report.event}] lock=${JSON.stringify(report.lockName)} tier=${report.backendTier} durationMs=${report.durationMs}${report.outcome ? ` outcome=${report.outcome}` : ""}${report.holderConnectionId ? ` holderConnectionId=${report.holderConnectionId}` : ""}${report.holderId ? ` holderId=${report.holderId}` : ""} — subscribe via configuration.getErrorEvents().on("framework-error", …) to route these reports to your bug reporter`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2aXNvcnktbG9jay10ZWxlbWV0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvYWR2aXNvcnktbG9jay10ZWxlbWV0cnkuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0NHO0FBRUg7Ozs7Ozs7Ozs7OztHQVlHO0FBRUg7Ozs7O0dBS0c7QUFFSCxpRkFBaUY7QUFDakYsTUFBTSxDQUFDLE1BQU0scUNBQXFDLEdBQUcsSUFBSSxDQUFBO0FBRXpELHNFQUFzRTtBQUN0RSxNQUFNLENBQUMsTUFBTSxrQ0FBa0MsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFBO0FBRTNEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsK0JBQStCLENBQUMsSUFBSTtJQUNsRCxNQUFNLFVBQVUsR0FBRyxJQUFJLEVBQUUscUJBQXFCLENBQUE7SUFDOUMsOENBQThDO0lBQzlDLE1BQU0sVUFBVSxHQUFHO1FBQ2pCLGFBQWEsRUFBRSxxQ0FBcUM7UUFDcEQsVUFBVSxFQUFFLGtDQUFrQztLQUMvQyxDQUFBO0lBRUQsSUFBSSxVQUFVLEVBQUUsYUFBYSxLQUFLLElBQUk7UUFBRSxVQUFVLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQTtTQUNsRSxJQUFJLE9BQU8sVUFBVSxFQUFFLGFBQWEsS0FBSyxRQUFRLElBQUksVUFBVSxDQUFDLGFBQWEsSUFBSSxDQUFDO1FBQUUsVUFBVSxDQUFDLGFBQWEsR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFBO0lBRTVJLElBQUksVUFBVSxFQUFFLFVBQVUsS0FBSyxJQUFJO1FBQUUsVUFBVSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUE7U0FDNUQsSUFBSSxPQUFPLFVBQVUsRUFBRSxVQUFVLEtBQUssUUFBUSxJQUFJLFVBQVUsQ0FBQyxVQUFVLElBQUksQ0FBQztRQUFFLFVBQVUsQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQTtJQUVoSSxPQUFPLFVBQVUsQ0FBQTtBQUNuQixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLFVBQVUsK0JBQStCLENBQUMsYUFBYSxFQUFFLE1BQU07SUFDbkUsK0RBQStEO0lBQy9ELElBQUksV0FBVyxDQUFBO0lBRWYsSUFBSSxDQUFDO1FBQ0gsV0FBVyxHQUFHLGFBQWEsRUFBRSxjQUFjLEVBQUUsQ0FBQTtJQUMvQyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTSxDQUFDLGtFQUFrRTtJQUMzRSxDQUFDO0lBRUQsSUFBSSxDQUFDLFdBQVc7UUFBRSxPQUFNO0lBRXhCLE1BQU0sV0FBVyxHQUFHLFdBQVcsQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDO1dBQy9ELFdBQVcsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQy9DLE1BQU0sT0FBTyxHQUFHLEVBQUMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLEdBQUcsTUFBTSxFQUFDLENBQUE7SUFFL0QsSUFBSSxDQUFDO1FBQ0gsV0FBVyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUM1QyxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFDLEdBQUcsT0FBTyxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBQyxDQUFDLENBQUE7SUFDM0UsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLDBEQUEwRDtJQUM1RCxDQUFDO0lBRUQsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2pCLE9BQU8sQ0FBQyxLQUFLLENBQUMsc0NBQXNDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsTUFBTSxDQUFDLFdBQVcsZUFBZSxNQUFNLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFlBQVksTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyx1QkFBdUIsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxzSEFBc0gsQ0FBQyxDQUFBO0lBQ2hlLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbi8qKlxuICogRXZlbnQtZHJpdmVuIGFkdmlzb3J5LWxvY2sgZHVyYXRpb24gdGVsZW1ldHJ5IChTVEMtMjYxLCBwYXJlbnQgZXBpYyBTVEMtMjA5KS5cbiAqXG4gKiBBIGxvY2sgY29udm95IGlzIG9ubHkgZml4YWJsZSB3aGVuIGl0IGlzICphdHRyaWJ1dGFibGUqOiB3aGljaCBsb2NrIG5hbWUgd2FzXG4gKiBjb250ZW5kZWQsIG9uIHdoaWNoIGJhY2tlbmQgdGllciwgZm9yIGhvdyBsb25nLCBhbmQgd2hvIGhlbGQgaXQuIFRoZXNlIHJlcG9ydHNcbiAqIGZpcmUgb24gdGhlIGFjcXVpc2l0aW9uL3JlbGVhc2UgZXZlbnRzIHRoZW1zZWx2ZXMg4oCUIG5ldmVyIGZyb20gYSBwZXJpb2RpY1xuICogc2Nhbm5lciDigJQgc28gYSBjb250ZW5kZWQgbG9jayBpbiBwcm9kdWN0aW9uIHN1cmZhY2VzIG9uIHRoZSBmcmFtZXdvcmstZXJyb3JcbiAqIGNoYW5uZWwgd2l0aCB0aGUgaG9sZGVyIGlkZW50aXR5IGF2YWlsYWJsZSBvbiB0aGF0IHRpZXIgYXQgdGhhdCBtb21lbnQsXG4gKiB3aXRob3V0IFNTSCBmb3JlbnNpY3MuXG4gKlxuICogVGhyZWUgZXZlbnRzLCBlYWNoIHdpdGggaXRzIG93biB0aHJlc2hvbGQgKGFsbCBjb25maWd1cmFibGUgcGVyIGRhdGFiYXNlIHZpYVxuICogYGFkdmlzb3J5TG9ja1RlbGVtZXRyeWAsIHNlZSBgZG9jcy9hZHZpc29yeS1sb2Nrcy5tZGApOlxuICpcbiAqIC0gYGFkdmlzb3J5LWxvY2stc2xvdy1hY3F1aXJlYCDigJQgYW4gYWNxdWlyZSB3YWl0IGNvbXBsZXRlZCBzbG93ZXIgdGhhblxuICogICBgc2xvd0FjcXVpcmVNc2AgKGRlZmF1bHQgNTAwMCksIGluY2x1ZGluZyB0aGUgZXZlbnR1YWwgb3V0Y29tZSAoYGFjcXVpcmVkYFxuICogICBvciBgdGltZW91dGApLlxuICogLSBgYWR2aXNvcnktbG9jay1hY3F1aXJlLXRpbWVvdXRgIOKAlCBhIHdhaXQgZXhjZWVkZWQgaXRzIHRpbWVvdXQuIFRoZSByZXBvcnRcbiAqICAgY2FycmllcyB0aGUgaG9sZGVyIGlkZW50aXR5IGF2YWlsYWJsZSBvbiB0aGUgdGllciBhdCB0aGF0IG1vbWVudDogdGhlXG4gKiAgIGRyaXZlci1uYXRpdmUgdGllcnMgYXR0cmlidXRlIHRoZSBob2xkZXIgY29ubmVjdGlvbiAoTWFyaWFEQlxuICogICBgSVNfVVNFRF9MT0NLYCwgUG9zdGdyZVNRTCBgcGdfbG9ja3NgIGpvaW5lZCB0byBgcGdfc3RhdF9hY3Rpdml0eWAsIFNRTFxuICogICBTZXJ2ZXIgYHN5cy5kbV90cmFuX2xvY2tzYCByZXF1ZXN0IHNlc3Npb24sIFNRTGl0ZSBOb2RlIGZpbGUgdGllclxuICogICBgb3duZXIuanNvbmAgcGlkL2hvc3RuYW1lKTsgdGhlIHByb2Nlc3MtbG9jYWwgdGllciByZXBvcnRzIHRoZSBvd25pbmdcbiAqICAgZHJpdmVyJ3MgYGhvbGRlcklkYC5cbiAqIC0gYGFkdmlzb3J5LWxvY2stc2xvdy1ob2xkYCDigJQgYSBob2xkIGxhc3RlZCBsb25nZXIgdGhhbiBgc2xvd0hvbGRNc2BcbiAqICAgKGRlZmF1bHQgNjAwMDApLCBlbWl0dGVkIGF0IHJlbGVhc2UuXG4gKlxuICogUmVwb3J0cyBhcmUgZW1pdHRlZCBvbiBgY29uZmlndXJhdGlvbi5nZXRFcnJvckV2ZW50cygpYCBhcyBgZnJhbWV3b3JrLWVycm9yYFxuICogKHBsdXMgdGhlIG1hdGNoaW5nIGBhbGwtZXJyb3JgKSB3aXRoIGB7Y29udGV4dDogXCJhZHZpc29yeS1sb2NrLXRlbGVtZXRyeVwiLFxuICogZXZlbnQsIGxvY2tOYW1lLCBiYWNrZW5kVGllciwgLi4ufWAgcGF5bG9hZHMsIG1hdGNoaW5nIHRoZSByZXBvJ3MgXCJuZXZlclxuICogc3dhbGxvd1wiIHJ1bGUgc28gcHJvY2Vzcy1sZXZlbCBidWcgcmVwb3J0ZXJzIGNhcHR1cmUgdGhlbS5cbiAqXG4gKiBIb2xkZXIgbG9va3VwcyBhcmUgc3RyaWN0bHkgYmVzdC1lZmZvcnQgKmFmdGVyKiB0aGUgYWNxdWlzaXRpb24gYWxyZWFkeVxuICogc2V0dGxlZDogYSBmYWlsZWQgbG9va3VwIG5ldmVyIGNoYW5nZXMgdGhlIGFjcXVpc2l0aW9uIG91dGNvbWUgYW5kIG5ldmVyXG4gKiB0aHJvd3MgdG8gdGhlIGNhbGxlci5cbiAqL1xuXG4vKipcbiAqIE9uZSBhZHZpc29yeS1sb2NrIHRlbGVtZXRyeSByZXBvcnQuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBBZHZpc29yeUxvY2tUZWxlbWV0cnlSZXBvcnRcbiAqIEBwcm9wZXJ0eSB7XCJhZHZpc29yeS1sb2NrLXNsb3ctYWNxdWlyZVwiIHwgXCJhZHZpc29yeS1sb2NrLWFjcXVpcmUtdGltZW91dFwiIHwgXCJhZHZpc29yeS1sb2NrLXNsb3ctaG9sZFwifSBldmVudCAtIFdoaWNoIGV2ZW50IGZpcmVkLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGxvY2tOYW1lIC0gVGhlIGNvbnRlbmRlZCBhZHZpc29yeS1sb2NrIG5hbWUuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gYmFja2VuZFRpZXIgLSBUaWVyIHRoYXQgc2VydmVkIChvciByZWZ1c2VkKSB0aGUgYWNxdWlzaXRpb246IGBkcml2ZXItbmF0aXZlYCwgYHByb2Nlc3MtbG9jYWxgLCBvciBgZmlsZWAuXG4gKiBAcHJvcGVydHkge251bWJlcn0gZHVyYXRpb25NcyAtIE1lYXN1cmVkIGR1cmF0aW9uIG9mIHRoZSBhY3F1aXJlIHdhaXQgKG9yIHRoZSBob2xkKS5cbiAqIEBwcm9wZXJ0eSB7XCJhY3F1aXJlZFwiIHwgXCJ0aW1lb3V0XCIgfCBudWxsfSBvdXRjb21lIC0gRm9yIGFjcXVpcmUgZXZlbnRzOiB3aGV0aGVyIHRoZSB3YWl0IGV2ZW50dWFsbHkgYWNxdWlyZWQgdGhlIGxvY2suIE51bGwgZm9yIGhvbGQgcmVwb3J0cy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyIHwgbnVsbH0gdGltZW91dE1zIC0gVGhlIGVmZmVjdGl2ZSBhY3F1aXJlIGJvdW5kIGZvciBhY3F1aXJlIGV2ZW50cy4gTnVsbCBmb3IgaG9sZCByZXBvcnRzIG9yIGFuIHVuYm91bmRlZCB3YWl0LlxuICogQHByb3BlcnR5IHtzdHJpbmcgfCBudWxsfSBob2xkZXJJZCAtIFByb2Nlc3MtbG9jYWwgaG9sZGVyIGF0dHJpYnV0aW9uIHdoZW4gdGhlIHRpZXIgY2FuIG5hbWUgaXRzIGxvY2FsIGhvbGRlci5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nIHwgbnVsbH0gaG9sZGVyQ29ubmVjdGlvbklkIC0gRHJpdmVyLW5hdGl2ZSBob2xkZXIgYXR0cmlidXRpb24gY2FwdHVyZWQgYXQgdGhlIGV2ZW50IG1vbWVudCAoTWFyaWFEQiBgSVNfVVNFRF9MT0NLYCBjb25uZWN0aW9uIGlkLCBQb3N0Z3JlU1FMIHBpZCwgU1FMIFNlcnZlciBzZXNzaW9uIGlkLCBTUUxpdGUgZmlsZSBgcGlkQGhvc3RuYW1lYCkuXG4gKiBAcHJvcGVydHkge3N0cmluZyB8IG51bGx9IGhvbGRlckxvb2t1cEVycm9yIC0gU2V0IHdoZW4gdGhlIGJlc3QtZWZmb3J0IGhvbGRlciBsb29rdXAgaXRzZWxmIGZhaWxlZDsgdGhlIGxvb2t1cCBuZXZlciBhZmZlY3RzIHRoZSBhY3F1aXNpdGlvbi5cbiAqL1xuXG4vKipcbiAqIFJlc29sdmVkIHBlci1kYXRhYmFzZSB0ZWxlbWV0cnkgdGhyZXNob2xkcy5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IEFkdmlzb3J5TG9ja1RlbGVtZXRyeVRocmVzaG9sZHNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyIHwgbnVsbH0gc2xvd0FjcXVpcmVNcyAtIFJlcG9ydCBhbiBhY3F1aXJlIHdhaXQgc2xvd2VyIHRoYW4gdGhpczsgYG51bGxgIGRpc2FibGVzIHNsb3ctYWNxdWlyZSByZXBvcnRzLlxuICogQHByb3BlcnR5IHtudW1iZXIgfCBudWxsfSBzbG93SG9sZE1zIC0gUmVwb3J0IGEgaG9sZCBsb25nZXIgdGhhbiB0aGlzIGF0IHJlbGVhc2U7IGBudWxsYCBkaXNhYmxlcyBob2xkIHJlcG9ydHMuXG4gKi9cblxuLyoqIEZyYW1ld29yayBkZWZhdWx0OiByZXBvcnQgYW4gYWNxdWlyZSB3YWl0IHRoYXQgY29tcGxldGVkIHNsb3dlciB0aGFuIHRoaXMuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9BRFZJU09SWV9MT0NLX1NMT1dfQUNRVUlSRV9NUyA9IDUwMDBcblxuLyoqIEZyYW1ld29yayBkZWZhdWx0OiByZXBvcnQgYSBob2xkIHRoYXQgb3V0bGl2ZXMgdGhpcyBhdCByZWxlYXNlLiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfQURWSVNPUllfTE9DS19TTE9XX0hPTERfTVMgPSA2MCAqIDEwMDBcblxuLyoqXG4gKiBSZXNvbHZlIHRoZSB0ZWxlbWV0cnkgdGhyZXNob2xkcyBmb3Igb25lIGRhdGFiYXNlIGNvbmZpZ3VyYXRpb24uXG4gKiBBbiBleHBsaWNpdCBwZXItZGF0YWJhc2UgYGFkdmlzb3J5TG9ja1RlbGVtZXRyeWAgdmFsdWUgd2luczsgYG51bGxgIG9wdHMgb3V0XG4gKiBvZiB0aGF0IHJlcG9ydDsgb25seSB3aGVuIG5laXRoZXIgaXMgY29uZmlndXJlZCBkb2VzIHRoZSBmcmFtZXdvcmsgZGVmYXVsdFxuICogYXBwbHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRGF0YWJhc2VDb25maWd1cmF0aW9uVHlwZX0gYXJncyAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gYXJncy5cbiAqIEByZXR1cm5zIHtBZHZpc29yeUxvY2tUZWxlbWV0cnlUaHJlc2hvbGRzfSAtIFJlc29sdmVkIHRocmVzaG9sZHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZHZpc29yeUxvY2tUZWxlbWV0cnlUaHJlc2hvbGRzKGFyZ3MpIHtcbiAgY29uc3QgY29uZmlndXJlZCA9IGFyZ3M/LmFkdmlzb3J5TG9ja1RlbGVtZXRyeVxuICAvKiogQHR5cGUge0Fkdmlzb3J5TG9ja1RlbGVtZXRyeVRocmVzaG9sZHN9ICovXG4gIGNvbnN0IHRocmVzaG9sZHMgPSB7XG4gICAgc2xvd0FjcXVpcmVNczogREVGQVVMVF9BRFZJU09SWV9MT0NLX1NMT1dfQUNRVUlSRV9NUyxcbiAgICBzbG93SG9sZE1zOiBERUZBVUxUX0FEVklTT1JZX0xPQ0tfU0xPV19IT0xEX01TXG4gIH1cblxuICBpZiAoY29uZmlndXJlZD8uc2xvd0FjcXVpcmVNcyA9PT0gbnVsbCkgdGhyZXNob2xkcy5zbG93QWNxdWlyZU1zID0gbnVsbFxuICBlbHNlIGlmICh0eXBlb2YgY29uZmlndXJlZD8uc2xvd0FjcXVpcmVNcyA9PT0gXCJudW1iZXJcIiAmJiBjb25maWd1cmVkLnNsb3dBY3F1aXJlTXMgPj0gMCkgdGhyZXNob2xkcy5zbG93QWNxdWlyZU1zID0gY29uZmlndXJlZC5zbG93QWNxdWlyZU1zXG5cbiAgaWYgKGNvbmZpZ3VyZWQ/LnNsb3dIb2xkTXMgPT09IG51bGwpIHRocmVzaG9sZHMuc2xvd0hvbGRNcyA9IG51bGxcbiAgZWxzZSBpZiAodHlwZW9mIGNvbmZpZ3VyZWQ/LnNsb3dIb2xkTXMgPT09IFwibnVtYmVyXCIgJiYgY29uZmlndXJlZC5zbG93SG9sZE1zID49IDApIHRocmVzaG9sZHMuc2xvd0hvbGRNcyA9IGNvbmZpZ3VyZWQuc2xvd0hvbGRNc1xuXG4gIHJldHVybiB0aHJlc2hvbGRzXG59XG5cbi8qKlxuICogRW1pdCBvbmUgdGVsZW1ldHJ5IHJlcG9ydCBvbiB0aGUgZnJhbWV3b3JrLWVycm9yIGNoYW5uZWwuXG4gKlxuICogTWlycm9ycyB0aGUgcmVwbydzIGZyYW1ld29yay1lcnJvciBlbWlzc2lvbiBzaGFwZSAoc2VlIGBjb25maWd1cmF0aW9uLmpzYFxuICogYF9yZXBvcnRCZWFjb25FcnJvcmApOiB3aGVuIG5vIGxpc3RlbmVyIGlzIGF0dGFjaGVkIHRvIGBmcmFtZXdvcmstZXJyb3JgIG9yXG4gKiBgYWxsLWVycm9yYCwgYSBvbmUtbGluZSBzdW1tYXJ5IGdvZXMgdG8gYHN0ZGVycmAgc28gYSBjb252b3kgaXMgbmV2ZXJcbiAqIGNvbXBsZXRlbHkgc2lsZW50LiBBIGxpc3RlbmVyIGZhaWx1cmUgY2FuIG5ldmVyIGJyZWFrIGxvY2sgaGFuZGxpbmcsIHNvXG4gKiBlbWlzc2lvbnMgYXJlIGd1YXJkZWQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gY29uZmlndXJhdGlvbiAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2Ugb3duaW5nIHRoZSBlcnJvciBjaGFubmVsLlxuICogQHBhcmFtIHtBZHZpc29yeUxvY2tUZWxlbWV0cnlSZXBvcnR9IHJlcG9ydCAtIFRoZSByZXBvcnQgcGF5bG9hZC5cbiAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVtaXRBZHZpc29yeUxvY2tUZWxlbWV0cnlSZXBvcnQoY29uZmlndXJhdGlvbiwgcmVwb3J0KSB7XG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiZXZlbnRlbWl0dGVyM1wiKS5FdmVudEVtaXR0ZXIgfCB1bmRlZmluZWR9ICovXG4gIGxldCBlcnJvckV2ZW50c1xuXG4gIHRyeSB7XG4gICAgZXJyb3JFdmVudHMgPSBjb25maWd1cmF0aW9uPy5nZXRFcnJvckV2ZW50cygpXG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiAvLyBObyBjb25maWd1cmF0aW9uIHRvIHJlcG9ydCB0aHJvdWdoIOKAlCBuZXZlciBicmVhayBsb2NrIGhhbmRsaW5nLlxuICB9XG5cbiAgaWYgKCFlcnJvckV2ZW50cykgcmV0dXJuXG5cbiAgY29uc3QgaGFzTGlzdGVuZXIgPSBlcnJvckV2ZW50cy5saXN0ZW5lckNvdW50KFwiZnJhbWV3b3JrLWVycm9yXCIpID4gMFxuICAgIHx8IGVycm9yRXZlbnRzLmxpc3RlbmVyQ291bnQoXCJhbGwtZXJyb3JcIikgPiAwXG4gIGNvbnN0IHBheWxvYWQgPSB7Y29udGV4dDogXCJhZHZpc29yeS1sb2NrLXRlbGVtZXRyeVwiLCAuLi5yZXBvcnR9XG5cbiAgdHJ5IHtcbiAgICBlcnJvckV2ZW50cy5lbWl0KFwiZnJhbWV3b3JrLWVycm9yXCIsIHBheWxvYWQpXG4gICAgZXJyb3JFdmVudHMuZW1pdChcImFsbC1lcnJvclwiLCB7Li4ucGF5bG9hZCwgZXJyb3JUeXBlOiBcImZyYW1ld29yay1lcnJvclwifSlcbiAgfSBjYXRjaCB7XG4gICAgLy8gQSBicm9rZW4gbGlzdGVuZXIgbXVzdCBuZXZlciBzdXJmYWNlIGFzIGEgbG9jayBmYWlsdXJlLlxuICB9XG5cbiAgaWYgKCFoYXNMaXN0ZW5lcikge1xuICAgIGNvbnNvbGUuZXJyb3IoYFt2ZWxvY2lvdXMgYWR2aXNvcnktbG9jay10ZWxlbWV0cnkgJHtyZXBvcnQuZXZlbnR9XSBsb2NrPSR7SlNPTi5zdHJpbmdpZnkocmVwb3J0LmxvY2tOYW1lKX0gdGllcj0ke3JlcG9ydC5iYWNrZW5kVGllcn0gZHVyYXRpb25Ncz0ke3JlcG9ydC5kdXJhdGlvbk1zfSR7cmVwb3J0Lm91dGNvbWUgPyBgIG91dGNvbWU9JHtyZXBvcnQub3V0Y29tZX1gIDogXCJcIn0ke3JlcG9ydC5ob2xkZXJDb25uZWN0aW9uSWQgPyBgIGhvbGRlckNvbm5lY3Rpb25JZD0ke3JlcG9ydC5ob2xkZXJDb25uZWN0aW9uSWR9YCA6IFwiXCJ9JHtyZXBvcnQuaG9sZGVySWQgPyBgIGhvbGRlcklkPSR7cmVwb3J0LmhvbGRlcklkfWAgOiBcIlwifSDigJQgc3Vic2NyaWJlIHZpYSBjb25maWd1cmF0aW9uLmdldEVycm9yRXZlbnRzKCkub24oXCJmcmFtZXdvcmstZXJyb3JcIiwg4oCmKSB0byByb3V0ZSB0aGVzZSByZXBvcnRzIHRvIHlvdXIgYnVnIHJlcG9ydGVyYClcbiAgfVxufVxuIl19
|
|
@@ -406,6 +406,18 @@ export default class VelociousDatabaseDriversBase {
|
|
|
406
406
|
}>;
|
|
407
407
|
/** @type {Map<string, number>} */
|
|
408
408
|
_heldAdvisoryLocks: Map<string, number>;
|
|
409
|
+
/**
|
|
410
|
+
* When each tracked advisory lock was first acquired, so the final release can
|
|
411
|
+
* report a hold that outlived `advisoryLockTelemetry.slowHoldMs`.
|
|
412
|
+
* @type {Map<string, number>}
|
|
413
|
+
*/
|
|
414
|
+
_advisoryLockAcquiredAtByName: Map<string, number>;
|
|
415
|
+
/**
|
|
416
|
+
* Stable per-connection holder identity used by advisory-lock telemetry when
|
|
417
|
+
* the tier can only name local holders.
|
|
418
|
+
* @type {string | undefined}
|
|
419
|
+
*/
|
|
420
|
+
_advisoryLockHolderId: string | undefined;
|
|
409
421
|
/**
|
|
410
422
|
* Exclusive operation lease installed by a single-multi-use pool.
|
|
411
423
|
* @type {import("../operation-lease.js").default | undefined}
|
|
@@ -1560,5 +1572,44 @@ export default class VelociousDatabaseDriversBase {
|
|
|
1560
1572
|
* @returns {Promise<boolean>} - Resolves to true if the lock is held by ? session.
|
|
1561
1573
|
*/
|
|
1562
1574
|
isAdvisoryLockHeld(name: string): Promise<boolean>;
|
|
1575
|
+
/**
|
|
1576
|
+
* Which advisory-lock backend tier this connection serves (STC-210 chain
|
|
1577
|
+
* naming). The base driver is the driver-native tier; the SQLite drivers
|
|
1578
|
+
* override to `process-local` / `file`.
|
|
1579
|
+
* @returns {string} - Tier name reported on telemetry payloads.
|
|
1580
|
+
*/
|
|
1581
|
+
advisoryLockBackendTier(): string;
|
|
1582
|
+
/**
|
|
1583
|
+
* Stable identity of this connection as a lock holder, reported on
|
|
1584
|
+
* telemetry payloads so a slow acquire/hold is attributable to the reporting
|
|
1585
|
+
* connection itself.
|
|
1586
|
+
* @returns {string} - Holder id.
|
|
1587
|
+
*/
|
|
1588
|
+
advisoryLockHolderId(): string;
|
|
1589
|
+
/**
|
|
1590
|
+
* Best-effort identity of the connection currently holding the named lock,
|
|
1591
|
+
* captured on the tier that served the acquisition. The base driver has no
|
|
1592
|
+
* portable server-side lookup; MySQL/PostgreSQL/SQL Server/Node-SQLite
|
|
1593
|
+
* override with their tier's holder attribution.
|
|
1594
|
+
* @param {string} name - Lock name.
|
|
1595
|
+
* @returns {Promise<string | null>} - Holder connection identity, or null when the tier cannot attribute it.
|
|
1596
|
+
*/
|
|
1597
|
+
advisoryLockHolderConnectionId(name: string): Promise<string | null>;
|
|
1598
|
+
/**
|
|
1599
|
+
* Emit one event-driven advisory-lock telemetry report (slow acquire,
|
|
1600
|
+
* acquire timeout with holder attribution, slow hold). The holder lookup is
|
|
1601
|
+
* best-effort: a failed lookup is recorded on the report and never affects
|
|
1602
|
+
* the acquisition that already settled.
|
|
1603
|
+
* @param {{event: "advisory-lock-slow-acquire" | "advisory-lock-acquire-timeout" | "advisory-lock-slow-hold", lockName: string, durationMs: number, outcome: "acquired" | "timeout" | null, timeoutMs: number | null, captureHolder?: boolean}} args - Report args.
|
|
1604
|
+
* @returns {Promise<void>} - Resolves after the report is emitted.
|
|
1605
|
+
*/
|
|
1606
|
+
_reportAdvisoryLockTelemetry(args: {
|
|
1607
|
+
event: "advisory-lock-slow-acquire" | "advisory-lock-acquire-timeout" | "advisory-lock-slow-hold";
|
|
1608
|
+
lockName: string;
|
|
1609
|
+
durationMs: number;
|
|
1610
|
+
outcome: "acquired" | "timeout" | null;
|
|
1611
|
+
timeoutMs: number | null;
|
|
1612
|
+
captureHolder?: boolean;
|
|
1613
|
+
}): Promise<void>;
|
|
1563
1614
|
}
|
|
1564
1615
|
//# sourceMappingURL=base.d.ts.map
|