My goal was to provide a small helper to retry fallible functions such as network requests and database calls. It supports jittering (adding randomness to wait time between retires) and a few simple retry strategies such as fixed, linear, and exponential.
I just started coding in Zig so I would appreciate any feedback such as
Is try retry.zretry(doWork, .{}, options) idiomatic Zig?
if passing function arguments as a tuple .{arg1, arg2} is awkward
should the caller need to provide the randomness or should the library create it if you need jittering
if you needed this sort of retry logic, would you import a module or implement it yourself?
if you find it useful, a star would be much appreciated.
I think this is great, good job. Personally, I’d implement it myself, mostly for the sake of minimal dependencies, but I can see this being used so I wouldn’t take that as a definitive answer.
A few things popped up in my head while I was reading the code:
You could return specific errors for the case where max attempts have been exhausted, or expose that in a dignostics object;
The former would be relevant if you’d add a distinction between errors that are retry-able those that should not be retried (as they’d almost always would mean failing again, i.e. HTTP 403);
I think the strategy for jittering is a bit off; You usually don’t want to randomize between 0 and delay_ms as that can have the effect of exhausting the attempts too quickly and not giving the proper time for state healing. What you’d typically want to do is to have a low threshold like 2~5ms, or perhaps 1~5% of the delay, for the sake of adding a minimal variance into requests that could be retried together, avoiding a thundering herd effect;
The pattern try wrapper(fn, args) is fairly common (see std.Io.async, for example);
I’d personally break options from the retry function, into a reusable Retrier struct, mostly for the ergonomics of not passing options in the same function call as the thing I want to retry on - perhaps RetryOptions could itself function as a reusable Retrier - not a great deal of problem though, that falls in the “taste” category
Overall really nice, good to see work in this direction
Thank you for your feedback
I’ll make sure to refactor the jittering strategy to a lower threshold as you mentioned and add the distinction between the errors that should and shouldn’t be retried.