Skip to content

Commit

Permalink
Merge branch 'develop' into multiInstance
Browse files Browse the repository at this point in the history
  • Loading branch information
lbwexler committed Nov 17, 2023
2 parents 8706413 + e653143 commit 095d339
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 19 deletions.
2 changes: 1 addition & 1 deletion svc/EnvironmentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export class EnvironmentService extends HoistService {
} else if (mode === 'forceReload') {
XH.suspendApp({
reason: 'APP_UPDATE',
message: `A new version of ${XH.clientAppName} is available!`
message: `A new version of ${XH.clientAppName} is now available (${appVersion}) and requires an immediate update.`
});
}
}
Expand Down
48 changes: 30 additions & 18 deletions utils/async/Timer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@ import {isBoolean, isFinite, isFunction, isNil, isString, pull} from 'lodash';
* Promise-aware recurring task timer for use by framework and applications.
*
* This object is designed to be robust across failing tasks, and never to re-run the task
* simultaneously, unless in the case of a timeout. Callers can optionally specify
* the duration of asynchronous tasks by returning a Promise from runFn.
* simultaneously, unless in the case of a timeout. Callers can optionally specify the duration
* of asynchronous tasks by returning a Promise from runFn.
*
* This object seeks to mirror the API and semantics of the server-side equivalent 'Timer'
* as closely as possible. However, there are important differences due to the synchronous
* nature of javascript. In particular, there is no support for 'runImmediatelyAndBlock', and the
* 'timeout' argument will not be able to interrupt synchronous activity of the runFn.
* This object seeks to mirror the API and semantics of `Timer.groovy` from Hoist Core as closely
* as possible. However, there are important differences due to the synchronous nature of
* javascript. In particular, there is no support for `runImmediatelyAndBlock`, and the `timeout`
* argument will not be able to interrupt synchronous activity of the runFn.
*
* All public properties should be considered read-only. See `setInterval()` to change the interval
* of this timer dynamically.
* All public properties should be considered read-only.
* See `setInterval()` to change the interval of this Timer dynamically.
*/
export class Timer {
static _timers: Timer[] = [];
static MIN_INTERVAL_MS = 500;

runFn: () => any = null;
interval: number | (() => number) = null;
Expand All @@ -41,6 +42,8 @@ export class Timer {
isRunning: boolean = false;
lastRun: Date = null;

private warnedIntervals = new Set();

/** Create a new Timer. */
static create({
runFn,
Expand All @@ -67,17 +70,14 @@ export class Timer {
this._timers = [];
}

/**
* Permanently cancel this timer.
*/
/** Permanently cancel this timer. */
cancel() {
this.cancelInternal();
pull(Timer._timers, this);
}

/**
* Change the interval of this timer.
*
* @param interval - ms to wait between runs or any value `<=0` to pause the timer.
*/
setInterval(interval: number) {
Expand All @@ -94,7 +94,10 @@ export class Timer {
this.intervalUnits = args.intervalUnits;
this.timeoutUnits = args.timeoutUnits;
this.delay = this.parseDelay(args.delay);
throwIf(this.interval == null || this.runFn == null, 'Missing req arguments for Timer');
throwIf(
this.interval == null || this.runFn == null,
'Missing required arguments for Timer - both interval and runFn must be specified.'
);

wait(this.delay).then(() => this.heartbeatAsync());
}
Expand Down Expand Up @@ -133,18 +136,27 @@ export class Timer {
return isString(val) ? () => XH.configService.get(val) : val;
}

private parseDelay(val): number {
private parseDelay(val: number | boolean): number {
if (isBoolean(val)) return val ? this.intervalMs : 0;
return isFinite(val) ? val : 0;
}

private get intervalMs() {
const {interval, intervalUnits} = this;
const {interval, intervalUnits, warnedIntervals} = this,
min = Timer.MIN_INTERVAL_MS;

if (isNil(interval)) return null;

let ret = (isFunction(interval) ? interval() : interval) * intervalUnits;
if (ret > 0 && ret < 500) {
console.warn('Timer cannot be set for values less than 500ms.');
ret = 500;

if (ret > 0 && ret < min) {
if (!warnedIntervals.has(ret)) {
warnedIntervals.add(ret);
console.warn(
`Timer interval of ${ret}ms requested - forcing to min interval of ${min}ms.`
);
}
ret = min;
}
return ret;
}
Expand Down

0 comments on commit 095d339

Please sign in to comment.