Skip to content

Commit

Permalink
fix: more interval logic
Browse files Browse the repository at this point in the history
  • Loading branch information
TurtIeSocks committed Aug 9, 2024
1 parent 7afbb09 commit 570eba2
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 26 deletions.
57 changes: 36 additions & 21 deletions server/src/services/Timer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ const { Logger } = require('@rm/logger')
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' })

const UNITS = /** @type {const} */ ([
{ unit: 'second', value: 1 },
{ unit: 'minute', value: 60 },
{ unit: 'hour', value: 3600 },
{ unit: 'day', value: 86400 },
{ unit: 'week', value: 604800 },
{ unit: 'month', value: 2592000 },
{ unit: 'year', value: 31536000 },
{ unit: 'month', value: 2592000 },
{ unit: 'week', value: 604800 },
{ unit: 'day', value: 86400 },
{ unit: 'hour', value: 3600 },
{ unit: 'minute', value: 60 },
{ unit: 'second', value: 1 },
])

class Timer extends Logger {
Expand All @@ -26,6 +26,7 @@ class Timer extends Logger {
this._intervalMs = (intervalHours || 0) * 60 * 60 * 1000
/** @type {Date} */
this._date = date

/** @type {NodeJS.Timeout | null} */
this._timer = null
/** @type {NodeJS.Timeout | null} */
Expand All @@ -41,31 +42,46 @@ class Timer extends Logger {
}

relative() {
const seconds = Math.floor(this.ms / 1000)
for (let i = UNITS.length - 1; i >= 0; i--) {
let seconds = Math.floor(this.ms / 1000)
const isNegative = seconds < 0
seconds = Math.abs(seconds)
const result = []

for (let i = 0; i < UNITS.length; i++) {
const { unit, value } = UNITS[i]
if (Math.abs(seconds) >= value) {
const count = Math.floor(seconds / value)
return rtf.format(count, unit)
const count = Math.floor(seconds / value)
if (count > 0) {
result.push(rtf.format(isNegative ? -count : count, unit))
seconds -= count * value
}
}

return rtf.format(seconds, 'second')
return result.length > 1
? `${result
.slice(0, -1)
.map((r, i) => {
if (i === 0) return r
const [, ...n] = r.split(' ')
return n.join(' ')
})
.join(', ')} and ${result[result.length - 1].replaceAll('in ', '')}`
: result[0]
}

setNextDate() {
this._date = new Date(this._date.getTime() + this._intervalMs)
this.log.info('next activation', this.relative())
this.log.info('next', this.relative())
}

/**
* @param {() => any | Promise<any>} cb
*/
setInterval(cb) {
if (this._intervalMs > 0) {
this._interval = setInterval(() => {
this.setNextDate()
this._interval = setInterval(async () => {
await cb()
this.setNextDate()
return cb()
}, this._intervalMs)
}
}
Expand All @@ -79,17 +95,16 @@ class Timer extends Logger {

if (now >= this._date.getTime()) {
this.setInterval(cb)
return false
return true
}
this.clear()
this.log.info('activating', this.relative())
this.log.info(this.relative())

this._timer = setTimeout(() => {
this._timer = setTimeout(async () => {
await cb()
this.setInterval(cb)
return cb()
}, this._date.getTime() - now)

return true
return false
}

async clear() {
Expand Down
27 changes: 24 additions & 3 deletions server/src/services/Trial.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ class Trial extends Logger {
this.log.info('next start:', startDate, 'next end:', endDate)
}

const now = Date.now()
this._active = startDate.getTime() < now && endDate.getTime() > now
if (this._active) {
this.log.info('found active trial')
}
this._startTimer = new Timer(
startDate,
this._trial.intervalHours,
Expand Down Expand Up @@ -98,6 +103,7 @@ class Trial extends Logger {
return async () => {
this.log.info('is', start ? 'starting' : 'ending')
await state.db.models.Session.clearNonDonor(this._name)
this._active = start
}
}

Expand All @@ -110,9 +116,24 @@ class Trial extends Logger {
}

active() {
return (
this._forceActive || (this._startTimer.ms <= 0 && this._endTimer.ms > 0)
)
return this._forceActive || this._active
}

status() {
const now = Date.now()
return {
active: this.active(),
start: {
raw: now + this._startTimer.ms,
date: this._startTimer._date.toISOString(),
relative: this._startTimer.relative(),
},
end: {
raw: now + this._endTimer.ms,
date: this._endTimer._date.toISOString(),
relative: this._endTimer.relative(),
},
}
}

start() {
Expand Down
4 changes: 2 additions & 2 deletions server/src/services/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ const serverState = {
getTrialStatus(strategy) {
if (strategy) {
if (strategy in this.event.authClients) {
return this.event.authClients[strategy].trialManager.active()
return this.event.authClients[strategy].trialManager.status()
}
throw new Error(`Strategy ${strategy} not found`)
} else {
return Object.fromEntries(
Object.entries(this.event.authClients).map(([k, v]) => [
k,
v.trialManager.active(),
v.trialManager.status(),
]),
)
}
Expand Down

0 comments on commit 570eba2

Please sign in to comment.