Skip to content

fix: recover faster after network outage (fixes #49) #131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
4 changes: 4 additions & 0 deletions lib/activity-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ export class ActivityState {
Zinnia.activity.info('SPARK retrieval reporting resumed')
}
}
//expose the healthy state
isHealthy() {
return this.#healthy === true
}
}
1 change: 1 addition & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export const RPC_AUTH = 'KZLIUb9ejreYOm-mZFM3UNADE0ux6CrHjxnS2D2Qgb8='
export const MINER_TO_PEERID_CONTRACT_ADDRESS =
'0x14183aD016Ddc83D638425D6328009aa390339Ce' // Contract address on the Filecoin EVM
export const MAX_REQUEST_DURATION_MS = 90_000
export const OFFLINE_RETRY_DELAY_MS = 5_000 // 5 seconds
10 changes: 8 additions & 2 deletions lib/spark.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
APPROX_ROUND_LENGTH_IN_MS,
MAX_JITTER_BETWEEN_TASKS_IN_MS,
MAX_REQUEST_DURATION_MS,
OFFLINE_RETRY_DELAY_MS,
} from './constants.js'
import { queryTheIndex } from './ipni-client.js'
import { assertOkResponse } from './http-assertions.js'
Expand Down Expand Up @@ -273,7 +274,10 @@ export default class Spark {
this.handleRunError(err)
}
const duration = Date.now() - started
const isHealthy = this.#activity.isHealthy()

const delay = calculateDelayBeforeNextTask({
isHealthy,
roundLengthInMs: APPROX_ROUND_LENGTH_IN_MS,
maxJitterInMs: MAX_JITTER_BETWEEN_TASKS_IN_MS,
maxTasksPerRound: this.#tasker.maxTasksPerRound,
Expand All @@ -282,8 +286,7 @@ export default class Spark {

if (delay > 0) {
console.log(
'Sleeping for %s seconds before starting the next task...',
Math.round(delay / 1000),
`${isHealthy ? 'Online' : 'Offline'} – sleeping for ${Math.round(delay / 1000)}s before next task.`,
)
await sleep(delay)
console.log() // add an empty line to visually delimit logs from different tasks
Expand All @@ -309,11 +312,14 @@ export default class Spark {
* @param {number} args.lastTaskDurationInMs
*/
export function calculateDelayBeforeNextTask({
isHealthy = true,
roundLengthInMs,
maxJitterInMs = 0,
maxTasksPerRound,
lastTaskDurationInMs,
}) {
if (!isHealthy) return OFFLINE_RETRY_DELAY_MS

const baseDelay = roundLengthInMs / maxTasksPerRound
const delay = baseDelay - lastTaskDurationInMs
const base = Math.min(delay, 60_000)
Expand Down
18 changes: 17 additions & 1 deletion test/spark.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
assertLessOrEqual,
assertGreaterOrEqual,
} from 'zinnia:assert'
import { SPARK_VERSION } from '../lib/constants.js'
import { SPARK_VERSION, OFFLINE_RETRY_DELAY_MS } from '../lib/constants.js'

const KNOWN_CID = 'bafkreih25dih6ug3xtj73vswccw423b56ilrwmnos4cbwhrceudopdp5sq'

Expand Down Expand Up @@ -504,6 +504,22 @@ test('calculateDelayBeforeNextTask() introduces random jitter for zero tasks in
)
})

test('calculateDelayBeforeNextTask() returns OFFLINE_RETRY_DELAY_MS when offline', () => {
const delay = calculateDelayBeforeNextTask({
isHealthy: false,
roundLengthInMs: 20 * 60_000,
maxJitterInMs: 10_000,
maxTasksPerRound: 1,
lastTaskDurationInMs: 1000,
})

assertEquals(
delay,
OFFLINE_RETRY_DELAY_MS,
`Expected delay to match OFFLINE_RETRY_DELAY_MS (${OFFLINE_RETRY_DELAY_MS}) when offline`,
)
})

test('fetchCAR triggers timeout after long retrieval', async () => {
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
const fetch = async (_url, { signal }) => {
Expand Down
Loading