Hi! I've been trying to write an HTTP server in Zig but the pg driver I'm using sometimes fails and I would like to retry the queries a max number of times before returning with the last error of the operation.
The solution so far that I could come up with is:
/// Retries a given fallible operation a max number of times.
pub fn retryOperation(comptime ReturnValue: type, config: RetryConfig, ctx: type) !ReturnValue {
if (config.max_retries < 1) {
return error.MaxRetriesReached;
}
return ctx.run() catch |err| {
uwu_log.logErr("Error in operation!").err(err).src(@src()).log();
return retryOperation(ReturnValue, .{ .max_retries = config.max_retries - 1 }, ctx);
};
}
Later I can use it like this:
/// Common logic for managing errors inside DB queries in transactions.
/// This method responds to the HTTP request, so no longer action is needed.
pub fn manageTransactionError(r: *const zap.Request, conn: *pg.Conn, err: anyerror) void {
manageQueryError(r, conn, err);
const Ctx = struct {
var connection: *pg.Conn = undefined;
pub fn run() !void {
return connection.rollback();
}
};
Ctx.connection = conn;
utils.db.retryOperation(void, .{}, Ctx) catch unreachable;
}
So far so good.