ravendb
Version:
RavenDB client for Node.js
96 lines • 3.5 kB
JavaScript
import { DateUtil } from "../../Utility/DateUtil.js";
import { HiloReturnCommand } from "./Commands/HiloReturnCommand.js";
import { NextHiloCommand } from "./Commands/NextHiloCommand.js";
import { HiloRangeValue } from "./HiloRangeValue.js";
import { Lazy } from "../Lazy.js";
export class HiloIdGenerator {
_store;
_tag;
_prefix = null;
_lastBatchSize = 0;
_lastRangeAt;
_dbName;
_identityPartsSeparator;
_range;
_nextRangeTask;
constructor(tag, store, dbName, identityPartsSeparator) {
this._store = store;
this._tag = tag;
this._dbName = dbName;
this._identityPartsSeparator = identityPartsSeparator;
this._lastRangeAt = DateUtil.zeroDate();
this._range = new HiloRangeValue(1, 0, null);
}
_getDocumentIdFromId(result) {
return this._prefix + result.id + "-" + result.serverTag;
}
// noinspection JSUnusedLocalSymbols
async generateDocumentId(entity) {
const nextId = await this.getNextId();
return this._getDocumentIdFromId(nextId);
}
async getNextId() {
// eslint-disable-next-line no-constant-condition
while (true) {
const current = this._nextRangeTask;
// local range is not exhausted yet
const range = this._range;
const id = range.increment();
if (id <= range.maxId) {
return {
id,
serverTag: range.serverTag
};
}
try {
// let's try to call the existing task for next range
await current.getValue();
if (range !== this._range) {
continue;
}
}
catch {
// previous task was faulted, we will try to replace it
}
// local range is exhausted , need to get a new range
const maybeNextTask = new Lazy(() => this._getNextRange());
let changed = false;
if (this._nextRangeTask === current) {
changed = true;
this._nextRangeTask = maybeNextTask;
}
if (changed) {
await maybeNextTask.getValue();
continue;
}
try {
// failed to replace, let's wait on the previous task
await this._nextRangeTask.getValue();
}
catch {
// previous task was faulted, we will try again
}
}
}
async _getNextRange() {
const hiloCmd = new NextHiloCommand(this._tag, this._lastBatchSize, this._lastRangeAt, this._identityPartsSeparator, this._range.maxId, this._store.conventions);
await this._store.getRequestExecutor(this._dbName).execute(hiloCmd);
const result = hiloCmd.result;
this._prefix = result.prefix;
this._lastBatchSize = result.lastSize;
this._lastRangeAt = result.lastRangeAt;
this._range = new HiloRangeValue(result.low, result.high, result.serverTag);
}
returnUnusedRange() {
const range = this._range;
const executor = this._store.getRequestExecutor(this._dbName);
return executor.execute(new HiloReturnCommand(this._tag, range.current, range.maxId));
}
get range() {
return this._range;
}
set range(value) {
this._range = value;
}
}
//# sourceMappingURL=HiloIdGenerator.js.map