Add time unit suffixes to variables (#561)

Add suffixes like Ms and Ns to variables whos time unit is not in
seconds.  This is aligning with a new code style of putting units
on variables that are not in SI base units.
This commit is contained in:
Hornwitser authored and GitHub committed 2024-01-20 13:26:55 +01:00
1 parent 9842705eb9
commit c53781d16c
38 files changed
+221 -201

No files matched your search

+12 -1
View File
@@ -19,6 +19,7 @@ Though we have some conventions and workflows that we kindly ask you to follow.
- [Supported Node.js and Factorio Version](#supported-node.js-and-factorio-version)
- [Code Style](#code-style)
- [Naming Style](#naming-style)
- [Units](#units)
- [Indenting](#indenting)
- [Line Length](#line-length)
- [Markdown](#markdown)
@@ -202,7 +203,7 @@ But there are at least a few things that have been agreed upon.
JavaScript variables in general uses camelCase.
The exception is for classes/constructors which use PascalCase and variables destructured from over the wire objects.
Fields in configs and messages sent over links uses lowercase_underscore.
Fields in configs uses lowercase_underscore.
JavaScript files are named using lowercase_underscore for files that export multiple items.
Files containing and exporting a single class should be named the same as the class in PascalCase.
@@ -217,6 +218,16 @@ Note that no sub-modules of the lib package is imported directly from the outsid
For lua code lowercase_underscore is used for everything.
### Units
When naming variables whos unit is not a base SI unit like seconds or metres the unit used should be suffixed in the variable name:
E.g.:
const startTimeMs = date.now();
const endNs = process.hrtime();
This makes it easier to spot different unit bases are being mixed in the code.
### Strings
+20 -20
View File
@@ -596,7 +596,7 @@ export default class Controller {
const host = HostInfo.fromJSON(json);
if (host.connected) {
host.connected = false;
host.updatedAt = Date.now();
host.updatedAtMs = Date.now();
}
hosts.set(id, host);
}
@@ -617,13 +617,13 @@ export default class Controller {
) as Static<typeof InstanceInfo.jsonSchema>[];
for (let json of serialized) {
if (!json.config) { // migrate: from pre Alpha 14 format.
json = { config: json as any, status: "running" }; // Use running to force updatedAt
json = { config: json as any, status: "running" }; // Use running to force updatedAtMs
}
const instance = InstanceInfo.fromJSON(json, "controller");
const status = instance.config.get("instance.assigned_host") === null ? "unassigned" : "unknown";
if (instance.status !== status) {
instance.status = status;
instance.updatedAt = Date.now();
instance.updatedAtMs = Date.now();
}
instances.set(instance.id, instance);
}
@@ -719,14 +719,14 @@ export default class Controller {
static addAppRoutes(app: Application, pluginInfos: any[]) {
app.use((req: Request, res: Response, next) => {
let start = process.hrtime.bigint();
let startNs = process.hrtime.bigint();
stream.finished(res, () => {
let routePath = "static";
if (req.route && req.route.path) {
routePath = req.route.path;
}
let end = process.hrtime.bigint();
endpointDurationSummary.labels(routePath).observe(Number(end - start) / 1e9);
let endNs = process.hrtime.bigint();
endpointDurationSummary.labels(routePath).observe(Number(endNs - startNs) / 1e9);
});
next();
});
@@ -759,7 +759,7 @@ export default class Controller {
async handleSystemInfoSubscription(request: lib.SubscriptionRequest) {
const systems = [...this.systems.values()].filter(
metric => metric.updatedAt > request.lastRequestTime,
metric => metric.updatedAtMs > request.lastRequestTimeMs,
);
return systems.length ? new lib.SystemInfoUpdateEvent(systems) : null;
}
@@ -780,7 +780,7 @@ export default class Controller {
hostsUpdated(hosts: HostInfo[]) {
const now = Date.now();
for (const host of hosts) {
host.updatedAt = now;
host.updatedAtMs = now;
}
this.hostsDirty = true;
let updates = hosts.map(host => host.toHostDetails());
@@ -789,7 +789,7 @@ export default class Controller {
async handleHostSubscription(request: lib.SubscriptionRequest) {
const hosts = [...this.hosts.values()].filter(
host => host.updatedAt > request.lastRequestTime,
host => host.updatedAtMs > request.lastRequestTimeMs,
).map(host => host.toHostDetails());
return hosts.length ? new lib.HostUpdatesEvent(hosts) : null;
}
@@ -937,7 +937,7 @@ export default class Controller {
);
} else {
instance.status = "unassigned";
instance.updatedAt = Date.now();
instance.updatedAtMs = Date.now();
this.instanceDetailsUpdated([instance]);
}
}
@@ -963,7 +963,7 @@ export default class Controller {
let prev = instance.status;
instance.status = "deleted";
instance.updatedAt = Date.now();
instance.updatedAtMs = Date.now();
this.instanceDetailsUpdated([instance]);
await lib.invokeHook(this.plugins, "onInstanceStatusChanged", instance, prev);
}
@@ -991,7 +991,7 @@ export default class Controller {
addInstanceHooks(instance: InstanceInfo) {
instance.config.on("fieldChanged", (field: string, curr: any, prev: any) => {
instance.updatedAt = Date.now();
instance.updatedAtMs = Date.now();
if (field === "instance.name") {
this.instanceDetailsUpdated([instance]);
}
@@ -1008,7 +1008,7 @@ export default class Controller {
async handleInstanceDetailsSubscription(request: lib.SubscriptionRequest) {
const instances = [...this.instances.values()].filter(
instance => instance.updatedAt > request.lastRequestTime,
instance => instance.updatedAtMs > request.lastRequestTimeMs,
).map(instance => instance.toInstanceDetails());
return instances.length ? new lib.InstanceDetailsUpdatesEvent(instances) : null;
}
@@ -1019,7 +1019,7 @@ export default class Controller {
}
async handleInstanceSaveDetailsSubscription(request: lib.SubscriptionRequest) {
const saves = [...this.saves.values()].filter(save => save.updatedAt > request.lastRequestTime);
const saves = [...this.saves.values()].filter(save => save.updatedAtMs > request.lastRequestTimeMs);
return saves.length ? new lib.InstanceSaveDetailsUpdatesEvent(saves) : null;
}
@@ -1027,7 +1027,7 @@ export default class Controller {
modPacksUpdated(modPacks: lib.ModPack[]) {
const now = Date.now();
for (const modPack of modPacks) {
modPack.updatedAt = now;
modPack.updatedAtMs = now;
}
this.modPacksDirty = true;
this.subscriptions.broadcast(new lib.ModPackUpdatesEvent(modPacks));
@@ -1036,20 +1036,20 @@ export default class Controller {
async handleModPackSubscription(request: lib.SubscriptionRequest) {
const modPacks = [...this.modPacks.values()].filter(
modPack => modPack.updatedAt > request.lastRequestTime,
modPack => modPack.updatedAtMs > request.lastRequestTimeMs,
);
return modPacks.length ? new lib.ModPackUpdatesEvent(modPacks) : null;
}
modsUpdated(mods: lib.ModInfo[]) {
// ModStore sets updatedAt for mods
// ModStore sets updatedAtMs for mods
this.subscriptions.broadcast(new lib.ModUpdatesEvent(mods));
lib.invokeHook(this.plugins, "onModsUpdated", mods);
}
async handleModSubscription(request: lib.SubscriptionRequest) {
const mods = [...this.modStore.files.values()].filter(
mod => mod.updatedAt > request.lastRequestTime,
mod => mod.updatedAtMs > request.lastRequestTimeMs,
);
return mods.length ? new lib.ModUpdatesEvent(mods) : null;
}
@@ -1057,7 +1057,7 @@ export default class Controller {
usersUpdated(users: ControllerUser[]) {
const now = Date.now();
for (const user of users) {
user.updatedAt = now;
user.updatedAtMs = now;
}
this.userManager.dirty = true;
this.subscriptions.broadcast(new lib.UserUpdatesEvent(users));
@@ -1065,7 +1065,7 @@ export default class Controller {
async handleUserSubscription(request: lib.SubscriptionRequest) {
const users = [...this.userManager.users.values()].filter(
user => user.updatedAt > request.lastRequestTime,
user => user.updatedAtMs > request.lastRequestTimeMs,
);
return users.length ? new lib.UserUpdatesEvent(users) : null;
}
+1 -1
View File
@@ -35,7 +35,7 @@ export default class ControllerUser extends User implements IControllerUser {
json.is_banned,
json.is_whitelisted,
json.ban_reason,
json.updated_at,
json.updated_at_ms,
json.is_deleted,
playerStats,
instanceStats,
+5 -5
View File
@@ -68,7 +68,7 @@ export default class HostConnection extends BaseConnection {
instances.push(instance);
let prev = instance.status;
instance.status = "unknown";
instance.updatedAt = now;
instance.updatedAtMs = now;
lib.invokeHook(this._controller.plugins, "onInstanceStatusChanged", instance, prev);
}
this._controller.instanceDetailsUpdated(instances);
@@ -185,7 +185,7 @@ export default class HostConnection extends BaseConnection {
let prev = instance.status;
instance.status = request.status;
instance.gamePort = request.gamePort;
instance.updatedAt = Date.now();
instance.updatedAtMs = Date.now();
logger.verbose(`Instance ${instance.config.get("instance.name")} State: ${instance.status}`);
this._controller.instanceDetailsUpdated([instance]);
await lib.invokeHook(this._controller.plugins, "onInstanceStatusChanged", instance, prev);
@@ -222,7 +222,7 @@ export default class HostConnection extends BaseConnection {
let prev = controllerInstance.status;
controllerInstance.status = instanceData.status;
controllerInstance.gamePort = instanceData.gamePort;
controllerInstance.updatedAt = Date.now();
controllerInstance.updatedAtMs = Date.now();
logger.verbose(`Instance ${instanceConfig.get("instance.name")} State: ${instanceData.status}`);
instanceUpdates.push(controllerInstance);
await lib.invokeHook(
@@ -283,7 +283,7 @@ export default class HostConnection extends BaseConnection {
if (existingSave && save.equals(existingSave)) {
continue;
}
save.updatedAt = now;
save.updatedAtMs = now;
this._controller.saves.set(save.id, save);
updates.push(save);
}
@@ -292,7 +292,7 @@ export default class HostConnection extends BaseConnection {
for (const [id, save] of this._controller.saves) {
if (save.instanceId === event.instanceId && !updatedSaves.has(id)) {
save.isDeleted = true;
save.updatedAt = now;
save.updatedAtMs = now;
updates.push(save);
this._controller.saves.delete(id);
}
+5 -5
View File
@@ -23,7 +23,7 @@ export default class HostInfo {
/** Unix timestamp in seconds host token must be issued after to be valid */
public tokenValidAfter: number = 0,
/** Millisecond Unix timestamp this entry was last updated at */
public updatedAt: number = 0,
public updatedAtMs: number = 0,
/** True if this host has been deleted */
public isDeleted: boolean = false,
) { }
@@ -37,7 +37,7 @@ export default class HostInfo {
"remote_address": Type.String(),
"public_address": Type.String(),
"token_valid_after": Type.Number(),
"updated_at": Type.Number(),
"updated_at_ms": Type.Number(),
"is_deleted": Type.Boolean(),
});
@@ -51,7 +51,7 @@ export default class HostInfo {
json.remote_address,
json.public_address,
json.token_valid_after,
json.updated_at,
json.updated_at_ms,
json.is_deleted,
);
}
@@ -66,7 +66,7 @@ export default class HostInfo {
remote_address: this.remoteAddress,
public_address: this.publicAddress,
token_valid_after: this.tokenValidAfter,
updated_at: this.updatedAt,
updated_at_ms: this.updatedAtMs,
is_deleted: this.isDeleted,
};
}
@@ -80,7 +80,7 @@ export default class HostInfo {
this.remoteAddress,
this.publicAddress,
this.tokenValidAfter,
this.updatedAt,
this.updatedAtMs,
this.isDeleted,
);
}
+3 -3
View File
@@ -67,10 +67,10 @@ export default class HttpCloser {
* If there's requests in progress that still haven't been completed
* after the timeout value passed they will be aborted.
*
* @param timeout -
* @param timeoutMs -
* Time in ms to wait for connections to close.
*/
async close(timeout:number = 5000): Promise<void> {
async close(timeoutMs: number = 5000): Promise<void> {
let activeSockets = new Set();
for (let response of this._responses) {
if (!response.headersSent) {
@@ -97,7 +97,7 @@ export default class HttpCloser {
// Node.js, see nodejs/node#27428.
socket.destroy();
}
}, timeout);
}, timeoutMs);
this._server.close(err => {
clearTimeout(timer);
if (err) {
+4 -4
View File
@@ -11,7 +11,7 @@ export default class InstanceInfo {
public config: lib.InstanceConfig,
public status: lib.InstanceStatus,
public gamePort?: number,
public updatedAt = 0,
public updatedAtMs = 0,
) {
this.config = config;
this.status = status;
@@ -21,7 +21,7 @@ export default class InstanceInfo {
"config": lib.InstanceConfig.jsonSchema,
"status": lib.InstanceStatus,
"gamePort": Type.Optional(Type.Number()),
"updatedAt": Type.Optional(Type.Number()),
"updatedAtMs": Type.Optional(Type.Number()),
});
static fromJSON(json: Static<typeof this.jsonSchema>, location: lib.ConfigLocation) {
@@ -29,7 +29,7 @@ export default class InstanceInfo {
lib.InstanceConfig.fromJSON(json.config, location),
json.status,
json.gamePort,
json.updatedAt,
json.updatedAtMs,
);
}
@@ -40,7 +40,7 @@ export default class InstanceInfo {
this.config.get("instance.assigned_host") ?? undefined,
this.gamePort,
this.status,
this.updatedAt,
this.updatedAtMs,
);
}
+2 -2
View File
@@ -56,7 +56,7 @@ async function getMetrics(req: Request, res: Response, next: any) {
}
let requests: Promise<InstanceType<typeof lib.HostMetricsRequest["Response"]> | null>[] = [];
let timeout = controller.config.get("controller.metrics_timeout") * 1000;
let timeoutMs = controller.config.get("controller.metrics_timeout") * 1000;
for (let [hostId, hostConnection] of controller.wsServer.hostConnections) {
if (!hostConnection.connected) {
continue;
@@ -68,7 +68,7 @@ async function getMetrics(req: Request, res: Response, next: any) {
}
return null;
}),
timeout, null
timeoutMs, null
));
}
+2 -2
View File
@@ -495,7 +495,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
}
async _loadPlugin(pluginInfo: lib.PluginNodeEnvInfo, host: Host) {
let pluginLoadStarted = Date.now();
let pluginLoadStartedMs = Date.now();
let InstancePluginClass = await lib.loadPluginClass(
pluginInfo.name,
path.posix.join(pluginInfo.requirePath, pluginInfo.instanceEntrypoint!),
@@ -506,7 +506,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
this.plugins.set(pluginInfo.name, instancePlugin);
await instancePlugin.init();
this.logger.info(`Loaded plugin ${pluginInfo.name} in ${Date.now() - pluginLoadStarted}ms`);
this.logger.info(`Loaded plugin ${pluginInfo.name} in ${Date.now() - pluginLoadStartedMs}ms`);
}
async _loadStats() {
+4 -4
View File
@@ -427,7 +427,7 @@ export interface FactorioServerOptions {
*/
maxConcurrentCommands?: number
/** Timeout in ms to wait for a response to a shutdown command. */
hangTimeout?: number,
hangTimeoutMs?: number,
}
/**
@@ -463,7 +463,7 @@ export class FactorioServer extends events.EventEmitter {
/** Enable verbose logging */
verboseLogging: boolean;
/** Timeout in ms to wait for a response to a shutdown command */
hangTimeout = 5000;
hangTimeoutMs = 5000;
_factorioDir: string;
_writeDir: string;
@@ -519,7 +519,7 @@ export class FactorioServer extends events.EventEmitter {
/** Maximum number of RCON commands transmitted in parallel on the RCON connection */
this.maxConcurrentCommands = options.maxConcurrentCommands || 5;
/** Timeout in ms to wait for a response to a shutdown command */
this.hangTimeout = options.hangTimeout ?? 5000;
this.hangTimeoutMs = options.hangTimeoutMs ?? 5000;
if (options.stripPaths) {
let charSet = new Set(path.resolve(this.writePath("temp")));
@@ -1012,7 +1012,7 @@ export class FactorioServer extends events.EventEmitter {
}
this._server!.kill("SIGKILL");
}
}, this.hangTimeout);
}, this.hangTimeoutMs);
// It's possible the server decides to exit on its own, in which
// case the stop operation has to be cancelled.
+4 -4
View File
@@ -30,7 +30,7 @@ export default class ExponentialBackoff {
reset: number;
private _exp = 0;
private _lastInvocationTime = Date.now();
private _lastInvocationTimeMs = Date.now();
/**
* Construct ExponentialBackoff helper
@@ -65,9 +65,9 @@ export default class ExponentialBackoff {
* @returns time in milliseconds to wait.
*/
delay() {
let invocationTime = Date.now();
let interval = (invocationTime - this._lastInvocationTime) / 1000;
this._lastInvocationTime = invocationTime;
let invocationTimeMs = Date.now();
let interval = (invocationTimeMs - this._lastInvocationTimeMs) / 1000;
this._lastInvocationTimeMs = invocationTimeMs;
if (interval > this.reset) {
this._exp = 0;
+1 -1
View File
@@ -56,7 +56,7 @@ export default class ModStore extends TypedEventEmitter<keyof ModStoreEvents, Mo
await fs.unlink(path.join(this.modsDirectory, file));
this.files.delete(file);
modInfo.isDeleted = true;
modInfo.updatedAt = Date.now();
modInfo.updatedAtMs = Date.now();
this.emit("change", modInfo);
}
+5 -5
View File
@@ -29,7 +29,7 @@ export default class RateLimiter {
*/
action?: () => void;
private _lastRun = 0;
private _lastRunMs = 0;
private _runTimeout?: ReturnType<typeof setTimeout>;
/**
@@ -60,15 +60,15 @@ export default class RateLimiter {
*/
activate() {
let now = Date.now();
if (now < this._lastRun + 1000 / this.maxRate) {
if (now < this._lastRunMs + 1000 / this.maxRate) {
if (!this._runTimeout && this.action) {
this._runTimeout = setTimeout(() => {
this._runTimeout = undefined;
this._lastRun = Date.now();
this._lastRunMs = Date.now();
if (this.action) {
this.action();
}
}, this._lastRun + 1000 / this.maxRate - now);
}, this._lastRunMs + 1000 / this.maxRate - now);
}
return false;
}
@@ -79,7 +79,7 @@ export default class RateLimiter {
this._runTimeout = undefined;
}
this._lastRun = now;
this._lastRunMs = now;
if (this.action) {
this.action();
}
+5 -5
View File
@@ -122,7 +122,7 @@ export default class ModInfo {
sha1?: string;
/** Millisecond Unix timestamp this entry was last updated at */
updatedAt = 0;
updatedAtMs = 0;
/**
* True if this mod has been deleted
@@ -148,7 +148,7 @@ export default class ModInfo {
...this.infoJsonSchema.properties,
"size": Type.Optional(Type.Integer()),
"sha1": Type.Optional(Type.String()),
"updated_at": Type.Optional(Type.Number()),
"updated_at_ms": Type.Optional(Type.Number()),
"is_deleted": Type.Optional(Type.Boolean()),
});
@@ -171,7 +171,7 @@ export default class ModInfo {
// Additional data
if (json.size) { modInfo.size = json.size; }
if (json.sha1) { modInfo.sha1 = json.sha1; }
if (json.updated_at) { modInfo.updatedAt = json.updated_at; }
if (json.updated_at_ms) { modInfo.updatedAtMs = json.updated_at_ms; }
if (json.is_deleted) { modInfo.isDeleted = json.is_deleted; }
return modInfo;
@@ -193,7 +193,7 @@ export default class ModInfo {
}
if (this.size) { json.size = this.size; }
if (this.sha1) { json.sha1 = this.sha1; }
if (this.updatedAt) { json.updated_at = this.updatedAt; }
if (this.updatedAtMs) { json.updated_at_ms = this.updatedAtMs; }
if (this.isDeleted) { json.is_deleted = this.isDeleted; }
return json;
}
@@ -229,7 +229,7 @@ export default class ModInfo {
size: stat.size,
sha1: await libHash.hashFile(modPath),
updated_at: stat.mtimeMs,
updated_at_ms: stat.mtimeMs,
is_deleted: false,
});
}
+6 -6
View File
@@ -102,7 +102,7 @@ export default class ModPack {
exportManifest?: ExportManifest;
/** Millisecond Unix timestamp this entry was last updated at */
updatedAt = 0;
updatedAtMs = 0;
/**
* True if this mod pack has been deleted from the list of mod packs.
@@ -118,7 +118,7 @@ export default class ModPack {
clone.mods = this.mods;
clone.settings = this.settings;
clone.exportManifest = this.exportManifest;
clone.updatedAt = this.updatedAt;
clone.updatedAtMs = this.updatedAtMs;
clone.isDeleted = this.isDeleted;
return clone;
}
@@ -135,7 +135,7 @@ export default class ModPack {
"runtime-per-user": ModSettingsJsonSchema,
}),
"export_manifest": Type.Optional(ExportManifest.jsonSchema),
"updated_at": Type.Optional(Type.Number()),
"updated_at_ms": Type.Optional(Type.Number()),
"is_deleted": Type.Optional(Type.Boolean()),
});
@@ -161,7 +161,7 @@ export default class ModPack {
};
}
if (json.export_manifest) { modPack.exportManifest = ExportManifest.fromJSON(json.export_manifest); }
if (json.updated_at) { modPack.updatedAt = json.updated_at; }
if (json.updated_at_ms) { modPack.updatedAtMs = json.updated_at_ms; }
if (json.is_deleted) { modPack.isDeleted = json.is_deleted; }
if (!modPack.mods.has("base")) {
@@ -185,7 +185,7 @@ export default class ModPack {
},
};
if (this.exportManifest) { json.export_manifest = this.exportManifest; }
if (this.updatedAt) { json.updated_at = this.updatedAt; }
if (this.updatedAtMs) { json.updated_at_ms = this.updatedAtMs; }
if (this.isDeleted) { json.is_deleted = this.isDeleted; }
return json;
}
@@ -194,7 +194,7 @@ export default class ModPack {
const json = this.toJSON();
delete json.id;
delete json.export_manifest;
delete json.updated_at;
delete json.updated_at_ms;
delete json.is_deleted;
// eslint-disable-next-line node/no-sync
+14 -11
View File
@@ -37,30 +37,33 @@ export default class PlayerStats {
static jsonSchema = Type.Object({
"join_count": Type.Optional(Type.Integer()),
"online_time_ms": Type.Optional(Type.Number()),
"first_join_at": Type.Optional(Type.Number()),
"first_join_at_ms": Type.Optional(Type.Number()),
"last_join_at_ms": Type.Optional(Type.Number()),
"last_leave_at_ms": Type.Optional(Type.Number()),
"last_leave_reason": Type.Optional(Type.String()),
// migrate: renamed fields from alpha 13
"last_join_at": Type.Optional(Type.Number()),
"last_leave_at": Type.Optional(Type.Number()),
"last_leave_reason": Type.Optional(Type.String()),
});
constructor(json: Static<typeof PlayerStats.jsonSchema> = {}) {
if (json["join_count"]) {
this.joinCount = json["join_count"];
}
if (json["first_join_at"]) {
this.firstJoinAt = new Date(json["first_join_at"]);
if (json["first_join_at_ms"]) {
this.firstJoinAt = new Date(json["first_join_at_ms"]);
}
if (json["online_time_ms"]) {
this.onlineTimeMs = json["online_time_ms"];
}
if (json["last_join_at"]) {
this.lastJoinAt = new Date(json["last_join_at"]);
if (json["last_join_at_ms"] ?? json["last_join_at"]) {
this.lastJoinAt = new Date(json["last_join_at_ms"] ?? json["last_join_at"]!);
if (!this.firstJoinAt) { // migrate: pre-alpha 14 did not have this field.
this.firstJoinAt = this.lastJoinAt;
}
}
if (json["last_leave_at"]) {
this.lastLeaveAt = new Date(json["last_leave_at"]);
if (json["last_leave_at_ms"] ?? json["last_leave_at"]) {
this.lastLeaveAt = new Date(json["last_leave_at_ms"] ?? json["last_leave_at"]!);
this.lastLeaveReason = json["last_leave_reason"] || "quit";
}
}
@@ -78,13 +81,13 @@ export default class PlayerStats {
json["online_time_ms"] = this.onlineTimeMs;
}
if (this.firstJoinAt) {
json["first_join_at"] = this.firstJoinAt.getTime();
json["first_join_at_ms"] = this.firstJoinAt.getTime();
}
if (this.lastJoinAt) {
json["last_join_at"] = this.lastJoinAt.getTime();
json["last_join_at_ms"] = this.lastJoinAt.getTime();
}
if (this.lastLeaveAt) {
json["last_leave_at"] = this.lastLeaveAt.getTime();
json["last_leave_at_ms"] = this.lastLeaveAt.getTime();
json["last_leave_reason"] = this.lastLeaveReason;
}
return json;
+5 -5
View File
@@ -24,7 +24,7 @@ export default class User {
/** Reason for being banned. Ignored if isBanned is false. */
public banReason = "",
/** Millisecond Unix timestamp this entry was last updated at */
public updatedAt = 0,
public updatedAtMs = 0,
/** True if this user object has been removed from the cluster. */
public isDeleted = false,
/** Combined statistics for the player this user account is tied to. */
@@ -42,7 +42,7 @@ export default class User {
is_banned: Type.Optional(Type.Boolean()),
is_whitelisted: Type.Optional(Type.Boolean()),
ban_reason: Type.Optional(Type.String()),
updated_at: Type.Optional(Type.Number()),
updated_at_ms: Type.Optional(Type.Number()),
is_deleted: Type.Optional(Type.Boolean()),
instance_stats: Type.Optional(
Type.Array(
@@ -67,7 +67,7 @@ export default class User {
json.is_banned,
json.is_whitelisted,
json.ban_reason,
json.updated_at,
json.updated_at_ms,
json.is_deleted,
playerStats,
instanceStats,
@@ -103,8 +103,8 @@ export default class User {
json.ban_reason = this.banReason;
}
if (this.updatedAt) {
json.updated_at = this.updatedAt;
if (this.updatedAtMs) {
json.updated_at_ms = this.updatedAtMs;
}
if (this.isDeleted) {
+3 -3
View File
@@ -239,7 +239,7 @@ export class SystemInfo {
public diskAvailable: number,
public canRestart: boolean,
/** Millisecond Unix timestamp this entry was last updated at */
public updatedAt: number,
public updatedAtMs: number,
public isDeleted: boolean,
) { }
@@ -256,7 +256,7 @@ export class SystemInfo {
"diskCapacity": Type.Number(),
"diskAvailable": Type.Number(),
"canRestart": Type.Boolean(),
"updatedAt": Type.Number(),
"updatedAtMs": Type.Number(),
"isDeleted": Type.Boolean(),
});
@@ -274,7 +274,7 @@ export class SystemInfo {
json.diskCapacity,
json.diskAvailable,
json.canRestart,
json.updatedAt,
json.updatedAtMs,
json.isDeleted,
);
}
+3 -3
View File
@@ -84,7 +84,7 @@ export class HostDetails {
public publicAddress: string = "",
public tokenValidAfter: number = 0,
/** Millisecond Unix timestamp this entry was last updated at */
public updatedAt = 0,
public updatedAtMs = 0,
public isDeleted = false,
) { }
@@ -96,7 +96,7 @@ export class HostDetails {
"remoteAddress": Type.Optional(Type.String()),
"publicAddress": Type.Optional(Type.String()),
"tokenValidAfter": Type.Optional(Type.Number()),
"updatedAt": Type.Optional(Type.Number()),
"updatedAtMs": Type.Optional(Type.Number()),
"isDeleted": Type.Optional(Type.Boolean()),
});
@@ -109,7 +109,7 @@ export class HostDetails {
json.remoteAddress,
json.publicAddress,
json.tokenValidAfter,
json.updatedAt,
json.updatedAtMs,
json.isDeleted,
);
}
+8 -8
View File
@@ -43,7 +43,7 @@ export class InstanceDetails {
public gamePort: number | undefined,
public status: InstanceStatus,
/** Millisecond Unix timestamp this entry was last updated at */
public updatedAt = 0,
public updatedAtMs = 0,
) { }
static jsonSchema = Type.Object({
@@ -55,7 +55,7 @@ export class InstanceDetails {
"unknown", "unassigned", "stopped", "starting", "running", "stopping",
"creating_save", "exporting_data", "deleted",
]),
"updatedAt": Type.Optional(Type.Number()),
"updatedAtMs": Type.Optional(Type.Number()),
});
static fromJSON(json: Static<typeof this.jsonSchema>) {
@@ -65,7 +65,7 @@ export class InstanceDetails {
json.assignedHost,
json.gamePort,
json.status,
json.updatedAt,
json.updatedAtMs,
);
}
@@ -289,7 +289,7 @@ export class SaveDetails {
public loaded: boolean,
public loadByDefault: boolean,
/** Millisecond Unix timestamp this entry was last updated at */
public updatedAt: number,
public updatedAtMs: number,
public isDeleted: boolean,
) { }
@@ -301,7 +301,7 @@ export class SaveDetails {
"mtimeMs": Type.Number(),
"loaded": Type.Boolean(),
"loadByDefault": Type.Boolean(),
"updatedAt": Type.Number(),
"updatedAtMs": Type.Number(),
"isDeleted": Type.Boolean(),
});
@@ -314,7 +314,7 @@ export class SaveDetails {
json.mtimeMs,
json.loaded,
json.loadByDefault,
json.updatedAt,
json.updatedAtMs,
json.isDeleted,
);
}
@@ -330,8 +330,8 @@ export class SaveDetails {
* @returns true if this save is identical to the provided save
*/
equals(other: SaveDetails) {
// Note that updatedAt is not included in the equality check because
// instances send the whole list of saves with updatedAt set to zero
// Note that updatedAtMs is not included in the equality check because
// instances send the whole list of saves with updatedAtMs set to zero
// to the controller whenever any save changes and this equals check
// is used to filter whether a save was updated.
return (
+6 -6
View File
@@ -22,10 +22,10 @@ export function basicType(value: unknown) {
/**
* Asynchronously wait for the given duration
*
* @param duration - Time to wait for in milliseconds.
* @param durationMs - Time to wait for in milliseconds.
*/
export async function wait(duration: number) {
await new Promise(resolve => { setTimeout(resolve, duration); });
export async function wait(durationMs: number) {
await new Promise(resolve => { setTimeout(resolve, durationMs); });
}
@@ -33,16 +33,16 @@ export async function wait(duration: number) {
* Resolve a promise with a timeout.
*
* @param {Promise} promise - Promise to wait for.
* @param {number} time - Maximum time im milliseconds to wait for.
* @param {number} limitMs - Maximum time im milliseconds to wait for.
* @param {*=} timeoutResult - Value to return if the operation timed out.
*/
export async function timeout<T>(promise: Promise<T>, time: number, timeoutResult: T) {
export async function timeout<T>(promise: Promise<T>, limitMs: number, timeoutResult: T) {
let timer: ReturnType<typeof setTimeout> | undefined;
try {
return await Promise.race([
promise,
new Promise<T>(resolve => {
timer = setTimeout(() => resolve(timeoutResult), time);
timer = setTimeout(() => resolve(timeoutResult), limitMs);
}),
]);
+15 -15
View File
@@ -95,7 +95,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
_state: ConnectorState = "closed";
_closing = false;
_socket: WebSocketClusterio | null = null;
_lastHeartbeat: number | null = null;
_lastHeartbeatMs: number | null = null;
_heartbeatId: ReturnType<typeof setInterval> | null = null;
_heartbeatInterval: number | null = null;
_lastReceivedSeq = undefined;
@@ -105,7 +105,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
this._state = "closed";
this._closing = false;
assert(this._socket === null);
this._lastHeartbeat = null;
this._lastHeartbeatMs = null;
assert(this._heartbeatId === null);
this._heartbeatInterval = null;
this._lastReceivedSeq = undefined;
@@ -117,7 +117,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
this._state = "connecting";
assert(this._closing === false);
assert(this._socket);
this._lastHeartbeat = null;
this._lastHeartbeatMs = null;
assert(this._heartbeatId === null);
this._heartbeatInterval = null;
this._lastReceivedSeq = undefined;
@@ -192,7 +192,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
_doHeartbeat() {
this._check("connected");
if (Date.now() - this._lastHeartbeat! > 2000 * this._heartbeatInterval!) {
if (Date.now() - this._lastHeartbeatMs! > 2000 * this._heartbeatInterval!) {
logger.verbose("Connector | closing after heartbeat timed out");
// eslint-disable-next-line node/no-process-env
if (process.env.APP_ENV === "browser") {
@@ -207,7 +207,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
}
_processHeartbeat(message: libData.MessageHeartbeat) {
this._lastHeartbeat = Date.now();
this._lastHeartbeatMs = Date.now();
this._dropSendBufferSeq(message.seq);
}
@@ -218,7 +218,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
if (this._heartbeatId) {
throw new Error("heartbeat is already running");
}
this._lastHeartbeat = Date.now();
this._lastHeartbeatMs = Date.now();
this._heartbeatId = setInterval(() => {
this._doHeartbeat();
}, this._heartbeatInterval! * 1000);
@@ -327,7 +327,7 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
_reconnectId?: ReturnType<typeof setTimeout>;
_sessionToken: string | null = null;
_sessionTimeout: number | null = null;
_startedResuming: number | null = null;
_startedResumingMs: number | null = null;
_backoff: ExponentialBackoff;
constructor(
@@ -350,7 +350,7 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
this._reconnectId = undefined;
this._sessionToken = null;
this._sessionTimeout = null;
this._startedResuming = null;
this._startedResumingMs = null;
super._reset();
this.src = undefined as any;
}
@@ -359,7 +359,7 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
assert(this._reconnectId === undefined);
this._sessionToken = null;
this._sessionTimeout = null;
this._startedResuming = null;
this._startedResumingMs = null;
super._invalidate();
this.src = undefined as any;
}
@@ -473,10 +473,10 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
logger.error("Unexpected double call to reconnect");
}
let delay = this._backoff.delay();
let delayMs = this._backoff.delay();
if (
this._state === "resuming"
&& this._startedResuming! + this._sessionTimeout! * 1000 < Date.now() + delay
&& this._startedResumingMs! + this._sessionTimeout! * 1000 < Date.now() + delayMs
) {
logger.error("Connector | Session timed out trying to resume");
this._reset();
@@ -489,12 +489,12 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
}
}
logger.verbose(
`Connector | waiting ${(Math.round(delay / 10) / 100)} seconds for reconnect`
`Connector | waiting ${(Math.round(delayMs / 10) / 100)} seconds for reconnect`
);
this._reconnectId = setTimeout(() => {
this._reconnectId = undefined;
this._doConnect();
}, delay);
}, delayMs);
}
_attachSocketHandlers() {
@@ -516,7 +516,7 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
} else {
this._state = "resuming";
this._startedResuming = Date.now();
this._startedResumingMs = Date.now();
this.reconnect();
this.emit("drop");
}
@@ -625,7 +625,7 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
for (let bufferedMessage of this._sendBuffer) {
this._sendInternal(bufferedMessage);
}
this._startedResuming = null;
this._startedResumingMs = null;
this.emit("resume");
} else if (type === "invalidate") {
+9 -9
View File
@@ -740,10 +740,10 @@ class GaugeChild extends ValueCollectorChild {
* seconds from when the timer was started
*/
startTimer() {
let start = process.hrtime.bigint();
let startNs = process.hrtime.bigint();
return () => {
let end = process.hrtime.bigint();
this.set(Number(end - start) / 1e9);
let endNs = process.hrtime.bigint();
this.set(Number(endNs - startNs) / 1e9);
};
}
}
@@ -979,10 +979,10 @@ class SummaryChild {
* when the timer was started into the metric.
*/
startTimer() {
let start = process.hrtime.bigint();
let startNs = process.hrtime.bigint();
return () => {
let end = process.hrtime.bigint();
this.observe(Number(end - start) / 1e9);
let endNs = process.hrtime.bigint();
this.observe(Number(endNs - startNs) / 1e9);
};
}
}
@@ -1260,10 +1260,10 @@ class HistogramChild {
* when the timer was started into the metric.
*/
startTimer() {
let start = process.hrtime.bigint();
let startNs = process.hrtime.bigint();
return () => {
let end = process.hrtime.bigint();
this.observe(Number(end - start) / 1e9);
let endNs = process.hrtime.bigint();
this.observe(Number(endNs - startNs) / 1e9);
};
}
}
+10 -10
View File
@@ -33,7 +33,7 @@ export class SubscriptionRequest {
constructor(
public eventName: string,
public subscribe: boolean,
public lastRequestTime: number = 0,
public lastRequestTimeMs: number = 0,
) {
if (!Link._eventsByName.has(eventName)) {
throw new Error(`Unregistered Event class ${eventName}`);
@@ -47,7 +47,7 @@ export class SubscriptionRequest {
]);
toJSON() {
return [this.eventName, this.subscribe, this.lastRequestTime];
return [this.eventName, this.subscribe, this.lastRequestTimeMs];
}
static fromJSON(json: Static<typeof SubscriptionRequest.jsonSchema>): SubscriptionRequest {
@@ -152,7 +152,7 @@ export class SubscriptionController {
export interface SubscribableValue {
id: number | string,
updatedAt: number,
updatedAtMs: number,
isDeleted: boolean,
}
@@ -175,8 +175,8 @@ export class EventSubscriber<
/** True if this subscriber is currently synced with the source */
synced = false;
_snapshot?: readonly [ReadonlyMap<K, Readonly<V>>, boolean];
_snapshotLastUpdated = 0;
lastResponseTime = -1;
_snapshotLastUpdatedMs = 0;
lastResponseTimeMs = -1;
constructor(
private Event: EventClass<T>,
@@ -203,7 +203,7 @@ export class EventSubscriber<
*/
async _handle(event: EventSubscribable<T, V>) {
for (const value of event.updates) {
this.lastResponseTime = Math.max(this.lastResponseTime, value.updatedAt);
this.lastResponseTimeMs = Math.max(this.lastResponseTimeMs, value.updatedAtMs);
if (value.isDeleted) {
this.values.delete(value.id as K);
} else {
@@ -257,8 +257,8 @@ export class EventSubscriber<
* @returns tuple of values map snapshot and synced property.
*/
getSnapshot() {
if (this._snapshotLastUpdated !== this.lastResponseTime) {
this._snapshotLastUpdated = this.lastResponseTime;
if (this._snapshotLastUpdatedMs !== this.lastResponseTimeMs) {
this._snapshotLastUpdatedMs = this.lastResponseTimeMs;
this._snapshot = [new Map(this.values), this.synced];
}
return this._snapshot!;
@@ -277,10 +277,10 @@ export class EventSubscriber<
await this.control.send(new SubscriptionRequest(
entry.name,
this._callbacks.length > 0,
this.lastResponseTime
this.lastResponseTimeMs
));
this.synced = this._callbacks.length > 0;
this._snapshotLastUpdated = 0;
this._snapshotLastUpdatedMs = 0;
for (let callback of this._callbacks) {
callback([], this.synced);
}
+2 -2
View File
@@ -31,7 +31,7 @@ export function formatDuration(ms: number): string {
return result;
}
export function formatTimestamp(timestamp: number): string {
export function formatTimestamp(timestampMs: number): string {
const options = {
year: "numeric",
month: "numeric",
@@ -39,5 +39,5 @@ export function formatTimestamp(timestamp: number): string {
hour: "numeric",
minute: "numeric",
} as const;
return new Intl.DateTimeFormat(undefined, options).format(new Date(timestamp));
return new Intl.DateTimeFormat(undefined, options).format(new Date(timestampMs));
}
+7 -7
View File
@@ -36,7 +36,7 @@ async function saveDatabase(
}
export class ControllerPlugin extends BaseControllerPlugin {
acquiredPlayers!: Map<string, { instanceId: number, expires?: number }>;
acquiredPlayers!: Map<string, { instanceId: number, expiresMs?: number }>;
playerDatastore!: Map<string, IpcPlayerData>;
playerDatastoreDirty = false;
@@ -62,18 +62,18 @@ export class ControllerPlugin extends BaseControllerPlugin {
}
if (["unknown", "stopped"].includes(instance.status)) {
let timeout = this.controller.config.get("inventory_sync.player_lock_timeout") * 1000;
let timeoutMs = this.controller.config.get("inventory_sync.player_lock_timeout") * 1000;
for (let acquisitonRecord of this.acquiredPlayers.values()) {
if (acquisitonRecord.instanceId === instanceId && !acquisitonRecord.expires) {
acquisitonRecord.expires = Date.now() + timeout;
if (acquisitonRecord.instanceId === instanceId && !acquisitonRecord.expiresMs) {
acquisitonRecord.expiresMs = Date.now() + timeoutMs;
}
}
}
if (instance.status === "running") {
for (let acquisitonRecord of this.acquiredPlayers.values()) {
if (acquisitonRecord.instanceId === instanceId && acquisitonRecord.expires) {
delete acquisitonRecord.expires;
if (acquisitonRecord.instanceId === instanceId && acquisitonRecord.expiresMs) {
delete acquisitonRecord.expiresMs;
}
}
}
@@ -85,7 +85,7 @@ export class ControllerPlugin extends BaseControllerPlugin {
!acquisitionRecord
|| acquisitionRecord.instanceId === instanceId
|| !this.controller.instances.has(acquisitionRecord.instanceId)
|| acquisitionRecord.expires && acquisitionRecord.expires < Date.now()
|| acquisitionRecord.expiresMs && acquisitionRecord.expiresMs < Date.now()
) {
this.acquiredPlayers.set(playerName, { instanceId });
return true;
+8 -8
View File
@@ -26,7 +26,7 @@ async function generateCode(length: number): Promise<string> {
}
type PlayerCode = { playerCode: string, verifyCode: string | null, expires: number };
type PlayerCode = { playerCode: string, verifyCode: string | null, expiresMs: number };
export class ControllerPlugin extends BaseControllerPlugin {
players!: Map<string, PlayerCode>;
@@ -39,7 +39,7 @@ export class ControllerPlugin extends BaseControllerPlugin {
setInterval(() => {
let now = Date.now();
for (let [player, entry] of this.players) {
if (entry.expires < now) {
if (entry.expiresMs < now) {
this.players.delete(player);
}
}
@@ -88,13 +88,13 @@ export class ControllerPlugin extends BaseControllerPlugin {
}
for (let entry of this.players.values()) {
if (entry.playerCode === playerCode && entry.expires > Date.now()) {
if (entry.playerCode === playerCode && entry.expiresMs > Date.now()) {
let verifyCode = await generateCode(this.controller.config.get("player_auth.code_length"));
let secret = Buffer.from(this.controller.config.get("controller.auth_secret"), "base64");
let verifyToken = jwt.sign(
{
aud: "player_auth.verify_code",
exp: Math.floor(entry.expires / 1000),
exp: Math.floor(entry.expiresMs / 1000),
verify_code: verifyCode,
player_code: playerCode,
},
@@ -150,7 +150,7 @@ export class ControllerPlugin extends BaseControllerPlugin {
}
for (let [player, entry] of this.players) {
if (entry.playerCode === playerCode && entry.expires > Date.now()) {
if (entry.playerCode === playerCode && entry.expiresMs > Date.now()) {
if (entry.verifyCode === verifyCode) {
let user = this.controller.userManager.users.get(player);
if (!user) {
@@ -174,8 +174,8 @@ export class ControllerPlugin extends BaseControllerPlugin {
async handleFetchPlayerCodeRequest(request: FetchPlayerCodeRequest) {
let playerCode = await generateCode(this.controller.config.get("player_auth.code_length"));
let expires = Date.now() + this.controller.config.get("player_auth.code_timeout") * 1000;
this.players.set(request.player, { playerCode, verifyCode: null, expires });
let expiresMs = Date.now() + this.controller.config.get("player_auth.code_timeout") * 1000;
this.players.set(request.player, { playerCode, verifyCode: null, expiresMs });
return { player_code: playerCode, controller_url: this.controller.getControllerUrl() };
}
@@ -183,7 +183,7 @@ export class ControllerPlugin extends BaseControllerPlugin {
let { player, verifyCode } = request;
let entry = this.players.get(player);
if (!entry || entry.expires < Date.now()) {
if (!entry || entry.expiresMs < Date.now()) {
throw new lib.RequestError("invalid player");
}
+19 -16
View File
@@ -123,8 +123,8 @@ describe("player_auth", function() {
}
});
it("should return invalid player_code if the code is expired", async function() {
let expires = Date.now() - 1000;
controllerPlugin.players.set("expired", { playerCode: "expried", verifyCode: null, expires });
let expiresMs = Date.now() - 1000;
controllerPlugin.players.set("expired", { playerCode: "expired", verifyCode: null, expiresMs });
let result = await phin({
url: `${controllerUrl}/api/player_auth/player_code`,
method: "POST",
@@ -134,8 +134,8 @@ describe("player_auth", function() {
assert.deepEqual(result.body, { error: true, message: "invalid player_code" });
});
it("should return a verify code and token if code is valid", async function() {
let expires = Date.now() + 1000;
controllerPlugin.players.set("valid", { playerCode: "valid", verifyCode: null, expires });
let expiresMs = Date.now() + 1000;
controllerPlugin.players.set("valid", { playerCode: "valid", verifyCode: null, expiresMs });
let result = await phin({
url: `${controllerUrl}/api/player_auth/player_code`,
method: "POST",
@@ -214,8 +214,8 @@ describe("player_auth", function() {
await verify({ aud: "not_player_auth" });
});
it("should return invalid player_code if the code is expired", async function() {
let expires = Date.now() - 1000;
controllerPlugin.players.set("expired", { playerCode: "expried", verifyCode: "verify", expires });
let expiresMs = Date.now() - 1000;
controllerPlugin.players.set("expired", { playerCode: "expired", verifyCode: "verify", expiresMs });
let result = await phin({
url: `${controllerUrl}/api/player_auth/verify`,
method: "POST",
@@ -233,8 +233,11 @@ describe("player_auth", function() {
assert.deepEqual(result.body, { error: true, message: "invalid player_code" });
});
it("should return verified false if verify code has not yet been set", async function() {
let expires = Date.now() + 1000;
controllerPlugin.players.set("unverified", { playerCode: "unverified", verifyCode: null, expires });
let expiresMs = Date.now() + 1000;
controllerPlugin.players.set(
"unverified",
{ playerCode: "unverified", verifyCode: null, expiresMs },
);
let result = await phin({
url: `${controllerUrl}/api/player_auth/verify`,
method: "POST",
@@ -252,8 +255,8 @@ describe("player_auth", function() {
assert.deepEqual(result.body, { verified: false });
});
it("should return error if user is missing", async function() {
let expires = Date.now() + 1000;
controllerPlugin.players.set("missing", { playerCode: "missing", verifyCode: "verify", expires });
let expiresMs = Date.now() + 1000;
controllerPlugin.players.set("missing", { playerCode: "missing", verifyCode: "verify", expiresMs });
let result = await phin({
url: `${controllerUrl}/api/player_auth/verify`,
method: "POST",
@@ -271,8 +274,8 @@ describe("player_auth", function() {
assert.deepEqual(result.body, { error: true, message: "invalid user" });
});
it("should return verified true with token if valid verification", async function() {
let expires = Date.now() + 1000;
controllerPlugin.players.set("player", { playerCode: "player", verifyCode: "verify", expires });
let expiresMs = Date.now() + 1000;
controllerPlugin.players.set("player", { playerCode: "player", verifyCode: "verify", expiresMs });
let result = await phin({
url: `${controllerUrl}/api/player_auth/verify`,
method: "POST",
@@ -299,8 +302,8 @@ describe("player_auth", function() {
);
assert(typeof result.player_code === "string", "no code returned");
assert(result.player_code.length === 10, "incorrect code length returned");
let expires = controllerPlugin.players.get("test").expires;
let msFromExpected = Math.abs(expires - Date.now() - 1000);
let expiresMs = controllerPlugin.players.get("test").expiresMs;
let msFromExpected = Math.abs(expiresMs - Date.now() - 1000);
assert(msFromExpected < 100, `expiry time expected outside window (${msFromExpected}ms)`);
});
});
@@ -315,8 +318,8 @@ describe("player_auth", function() {
);
});
it("should throw if player code has expired", async function() {
let expires = Date.now() - 1000;
controllerPlugin.players.set("expired", { playerCode: "expried", verifyCode: null, expires });
let expiresMs = Date.now() - 1000;
controllerPlugin.players.set("expired", { playerCode: "expired", verifyCode: null, expiresMs });
await assert.rejects(
controllerPlugin.handleSetVerifyCodeRequest(
new SetVerifyCodeRequest("expired", "expired")
+2 -2
View File
@@ -109,8 +109,8 @@ export class InstancePlugin extends BaseInstancePlugin {
// take a long time for the command to go through if the command
// stream is overloaded. Should the timeout be exceeded the
// previous values for the metrics will end up being sent to controller.
let timeout = this.instance.config.get("statistics_exporter.command_timeout") * 1000;
await lib.timeout(this.gatherMetrics(), timeout, undefined);
let timeoutMs = this.instance.config.get("statistics_exporter.command_timeout") * 1000;
await lib.timeout(this.gatherMetrics(), timeoutMs, undefined);
}
}
+1 -1
View File
@@ -22,7 +22,7 @@ describe("controller/InstanceInfo", function() {
check(InstanceInfo.fromJSON({ config, status: "stopped" }, "controller"));
check(InstanceInfo.fromJSON({ config, status: "running" }, "controller"));
check(InstanceInfo.fromJSON({ config, status: "running", gamePort: 34197 }, "controller"));
check(InstanceInfo.fromJSON({ config, status: "running", updatedAt: Date.now() }, "controller"));
check(InstanceInfo.fromJSON({ config, status: "running", updatedAtMs: Date.now() }, "controller"));
// All at once
check(InstanceInfo.fromJSON({
+6 -6
View File
@@ -64,7 +64,7 @@ describe("class Instance", function() {
"player",
new PlayerStats({
join_count: 1,
last_join_at: stats.lastJoinAt.getTime(),
last_join_at_ms: stats.lastJoinAt.getTime(),
})
)
),
@@ -111,8 +111,8 @@ describe("class Instance", function() {
new PlayerStats({
join_count: 1,
online_time_ms: stats.onlineTimeMs,
last_join_at: stats.lastJoinAt.getTime(),
last_leave_at: stats.lastLeaveAt.getTime(),
last_join_at_ms: stats.lastJoinAt.getTime(),
last_leave_at_ms: stats.lastLeaveAt.getTime(),
last_leave_reason: "quit",
}),
"quit",
@@ -162,7 +162,7 @@ describe("class Instance", function() {
"foo",
new PlayerStats({
join_count: 1,
last_join_at: stats.lastJoinAt.getTime(),
last_join_at_ms: stats.lastJoinAt.getTime(),
})
)
)
@@ -185,8 +185,8 @@ describe("class Instance", function() {
new PlayerStats({
join_count: 1,
online_time_ms: stats.onlineTimeMs,
last_join_at: stats.lastJoinAt.getTime(),
last_leave_at: stats.lastLeaveAt.getTime(),
last_join_at_ms: stats.lastJoinAt.getTime(),
last_leave_at_ms: stats.lastLeaveAt.getTime(),
last_leave_reason: "quit",
}),
"quit",
+1 -1
View File
@@ -214,7 +214,7 @@ describe("host/server", function() {
if (process.platform === "win32") {
this.skip();
}
server.hangTimeout = 20;
server.hangTimeoutMs = 20;
server._server = new events.EventEmitter();
server._server.kill = () => true;
server._state = "running";
+3 -3
View File
@@ -113,7 +113,7 @@ describe("Integration of Clusterio", function() {
let controlB = new TestControl(connectorB);
connectorB._sessionToken = connectorA._sessionToken;
connectorB._sessionTimeout = connectorA._sessionTimeout;
connectorB._startedResuming = Date.now();
connectorB._startedResumingMs = Date.now();
connectorB._state = "resuming";
connectorB._doConnect();
await events.once(connectorB, "resume");
@@ -898,7 +898,7 @@ describe("Integration of Clusterio", function() {
reference.settings["runtime-global"].set("MyInt", { value: 1235 });
reference.settings["runtime-global"].set("MyDouble", { value: 12.25 });
reference.settings["runtime-per-user"].set("MyString", { value: "a-string" });
reference.updatedAt = modPack.updatedAt;
reference.updatedAtMs = modPack.updatedAtMs;
assert.deepEqual(modPack, reference);
});
});
@@ -1003,7 +1003,7 @@ describe("Integration of Clusterio", function() {
"dependencies:\n" +
`size: ${stat.size}\n` +
`sha1: ${hash}\n` +
`updatedAt: ${stat.mtimeMs}\n` +
`updatedAtMs: ${stat.mtimeMs}\n` +
"isDeleted: false\n",
);
});
+3 -3
View File
@@ -36,7 +36,7 @@ describe("lib/ExponentialBackoff", function() {
for (let max of [0.1, 0.5, 1, 2, 50, 100, 1000, 100000]) {
let backoff = new ExponentialBackoff({ base: 1, max });
for (let j = 0; j < 100; j++) {
let value = backoff.delay() / 1000; // Divide by 100 for ms to s conversion
let value = backoff.delay() / 1000; // Divide by 1000 for ms to s conversion
assert(value <= max, `delay returned a value greater than max: ${value} > ${max}`);
}
}
@@ -46,10 +46,10 @@ describe("lib/ExponentialBackoff", function() {
let backoff = new ExponentialBackoff({ reset: 100 });
backoff.delay();
assert.equal(backoff._exp, 1);
backoff._lastInvocationTime = Date.now() - 99 * 1000;
backoff._lastInvocationTimeMs = Date.now() - 99 * 1000;
backoff.delay();
assert.equal(backoff._exp, 2);
backoff._lastInvocationTime = Date.now() - 101 * 1000;
backoff._lastInvocationTimeMs = Date.now() - 101 * 1000;
backoff.delay();
assert.equal(backoff._exp, 1);
});
+1 -1
View File
@@ -92,7 +92,7 @@ describe("lib/data/ModInfo", function() {
dependencies: [],
filename: "empty_mod_1.0.0.zip",
size: stat.size,
updated_at: stat.mtimeMs,
updated_at_ms: stat.mtimeMs,
sha1: hash,
})
);
+7 -7
View File
@@ -28,15 +28,15 @@ describe("lib/data/User", function() {
[1, {
join_count: 1,
online_time_ms: 60e3,
last_join_at: new Date("2020-05T12:00Z").getTime(),
last_leave_at: new Date("2020-05T12:01Z").getTime(),
last_join_at_ms: new Date("2020-05T12:00Z").getTime(),
last_leave_at_ms: new Date("2020-05T12:01Z").getTime(),
last_leave_reason: "quit",
}],
[2, {
join_count: 1,
online_time_ms: 0,
first_join_at: new Date("2020-05T12:00Z").getTime(),
last_join_at: new Date("2020-05T12:02Z").getTime(),
first_join_at_ms: new Date("2020-05T12:00Z").getTime(),
last_join_at_ms: new Date("2020-05T12:02Z").getTime(),
}],
]});
@@ -52,9 +52,9 @@ describe("lib/data/User", function() {
lib.PlayerStats.fromJSON({
join_count: 2,
online_time_ms: 120e3,
first_join_at: new Date("2020-05T11:00Z").getTime(),
last_join_at: new Date("2020-05T13:00Z").getTime(),
last_leave_at: new Date("2020-05T13:02Z").getTime(),
first_join_at_ms: new Date("2020-05T11:00Z").getTime(),
last_join_at_ms: new Date("2020-05T13:00Z").getTime(),
last_leave_at_ms: new Date("2020-05T13:02Z").getTime(),
last_leave_reason: "afk",
}),
);
+2 -2
View File
@@ -21,10 +21,10 @@ describe("lib/helpers", function() {
it("should wait the approximate amount of time given", async function() {
let startNs = hrtime();
await lib.wait(100);
let duration = Number(hrtime() - startNs) / 1e6;
let durationMs = Number(hrtime() - startNs) / 1e6;
// On windows the time waited is normally up to 15 ms late with outliers in the 20ms range.
assert(duration > 90 && duration < 130, `duration (${duration}ms) not within (90-130)`);
assert(durationMs > 90 && durationMs < 130, `duration (${durationMs}ms) not within (90-130)`);
});
});
+7 -4
View File
@@ -347,7 +347,7 @@ describe("lib/subscriptions", function() {
it("should allow subscriptions to an event", async function() {
let calledWith = null;
let calledWithTwo = null;
const item = { id: 1, updatedAt: 1, isDeleted: false };
const item = { id: 1, updatedAtMs: 1, isDeleted: false };
const event = new RegisteredEvent([item]);
registeredEvent.subscribe(function(updates, synced) { calledWith = [updates, synced]; });
registeredEvent.subscribe(function(updates, synced) { calledWithTwo = [updates, synced]; });
@@ -382,9 +382,12 @@ describe("lib/subscriptions", function() {
describe("getSnapshot()", function() {
it("should give an immutable copy of the tracked values", async function() {
const update1 = [{ id: 1, updatedAt: 1, isDeleted: false }];
const update2 = [{ id: 1, updatedAt: 2, isDeleted: false }, { id: 2, updatedAt: 3, isDeleted: false }];
const update3 = [{ id: 1, updatedAt: 4, isDeleted: true }];
const update1 = [{ id: 1, updatedAtMs: 1, isDeleted: false }];
const update2 = [
{ id: 1, updatedAtMs: 2, isDeleted: false },
{ id: 2, updatedAtMs: 3, isDeleted: false },
];
const update3 = [{ id: 1, updatedAtMs: 4, isDeleted: true }];
const snap0 = registeredEvent.getSnapshot();
assert.deepEqual(snap0, [new Map(), false]);
await registeredEvent._handle(new RegisteredEvent(update1));