Skip to content
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

Implement timeouts and retries logic #75

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

MOZGIII
Copy link

@MOZGIII MOZGIII commented Sep 4, 2022

Closes #72.

@MOZGIII MOZGIII mentioned this pull request Sep 4, 2022
Copy link
Owner

@Swatinem Swatinem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That turned out really simple indeed. I left a couple of comments.
Otherwise you can leave out the dist files from the PR, I will rebuild those anyway on my end.

@@ -14,6 +14,12 @@ inputs:
workspaces:
description: "Paths to multiple Cargo workspaces and their target directories, separated by newlines"
required: false
maxRetryAttempts:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
maxRetryAttempts:
max-retries:

Maybe? To rather use dashed names to be consistent wtih the other options.

: new Promise<never>(() => {});

const timeoutSym = Symbol("timeout" as const);
const racingTimeout = timeout.then(() => timeoutSym);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const racingTimeout = timeout.then(() => timeoutSym);
const racingTimeout = timeout.then(() => { throw new TimeoutError("operation timeout"); });

This way you shouldn’t need the symbol and explicit check, just return await Promise.race

Comment on lines +38 to +46
const restoreKey = await withRetries(
() =>
withTimeout(
() => cache.restoreCache(config.cachePaths, key, [config.restoreKey]),
config.timeout
),
config.maxRetryAttempts,
() => true
);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The composition is nice, but the construct still looks very unweildy looking at it, I wonder if you can package that up into a single fn?

Copy link

@thomaseizinger thomaseizinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for making this! I am very interested in seeing this merged. Happy to take of the PR if you are busy @MOZGIII!

/** The max timeout for the networking operations */
public timeout: null | number = null;
/** The max retry attemtps for the networking operations */
public maxRetryAttempts: number = 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is 0 a useful default? Can we set this to 1 instead?

Comment on lines +30 to +31
/** The max timeout for the networking operations */
public timeout: null | number = null;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, I think a default value would be useful.

Typically, GitHub downloads the cache with > 100MB/s. Considering that the cache limit is 10GB per repository, downloading a cache shouldn't take much longer that 100 seconds. What about a default value of 2 minutes?

export async function withRetries<T>(
operation: () => Promise<T>,
maxRetryAttempts: number,
isRetriable: (error: unknown) => boolean

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The abstraction is nice but we pass () => true here in both usages so perhaps keep it lean and remove that?

Comment on lines +68 to +76
await withRetries(
() =>
withTimeout(
() => cache.saveCache(config.cachePaths, config.cacheKey),
config.timeout
),
config.maxRetryAttempts,
() => true
);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my experience, saving the cache never failed. Caches are also a lot less often saved compared to being restored so hitting rate limits / getting bandwidth-limited is likely a lot less frequent.

I do understand though that we might want to keep this for consistencies' sake.

@MOZGIII
Copy link
Author

MOZGIII commented Jan 24, 2023

I forgot about this one, @thomaseizinger please do

@thomaseizinger
Copy link

I forgot about this one, @thomaseizinger please do

I am currently trialing a different solution: libp2p/rust-libp2p#3376

@gautamg795
Copy link

FYI, https://github.com/actions/cache now includes timeouts by default (and they are configurable by environment variables).
I think just updating the dependency will add the feature for free to this action!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Timeout and restart
4 participants