feathers
feathers copied to clipboard
Requests retries
It's more of a feature request to feathers-client rather than an issue. Currently, in my project, I'm trying to repeat requests when the request times out or gets rate-limited. I can't find an easy way to handle it globally in feathers.
I was thinking about doing in on the error hook, however, there is an issue on how to repeat request. When I send a request using feathers-client, it will fire all hooks (in the client) again and we don't want that (I would need to set some flag to skip all hooks).
For now, only option that I've found is for sockets transport to overload emit method.
Is there a possibility to add some middleware or some hook to feathers client that would allow to retry requests? Or maybe already there is a better method to achieve request repeats?
@dryna You can try to use
const skippable = (hookName, hookFunc) => {
return context => {
if (context.params.skipHooks) {
const { type } = context;
const { skipHooks } = context.params;
if (
skipHooks.includes(hookName) ||
skipHooks.includes('all') ||
(skipHooks.includes('before') && type === 'before') ||
(skipHooks.includes('after') && type === 'after')
) {
return context;
} else {
return hookFunc(context);
}
} else {
return hookFunc(context);
}
};
};
This requires that you wrap your hook declarations such as
const myHook = skippable('myHook', context => {
// do stuff her
});
Then you can call the service again in the error hook like so
// this is super basic and would require more attention to what methog to call, etc
// this is just showing how to pass skipHooks
const result = await context.service.get(context.id, { ...context.params, skipHooks: ['all'] })
I am not sure you really could skip all hooks. Many feathers plugins, such as feathers-authentication-client, rely on hooks to do things within the app.
For example: https://github.com/feathersjs/feathers/blob/master/packages/authentication-client/src/hooks/populate-header.ts
That hooks populates the headers onto params that the service needs in order to retry that failed call.
So I think there has to be some protocol, such as skipHooks, to allow you to determine which hooks to skip.
Came across this while looking for retry options for auth / JWT expiration scenarios.
My request is, rather than provisioning options for developers to somehow achieve retries, it would be great if the framework abstracts it out and provides built-in retries as the natural way of any service call.
For example, currently we get Timeout error (when the server is offline) and NotAuthenticated errors (for auth expiration / failure). Usually these are retriable errors (with certain limit).
Similar to hooks, if retry options can be set to every service (and globally for the app), overridable at the individual call level, such as the number of retry attempts, delay exponentiation, max delay, and the kind of errors to retry, etc., and every service call is then retried automatically based on those settings, it would greatly improve the dev ux. (Similar to socket.io reconnects etc.)
It would take away one big headache for the dev in designing the components. Currently we have to carefully tag every service call with catch handlers and do unpleasant code juggles to retry the call for certain number of tries before failing, not so elegant and unnecessarily repeated code.
Also, in a micro-services scenario with complex dependencies amongst services, retries could prove to be helpful for self-regulating services (auto switch-on and shutdown), as noted here https://github.com/feathersjs/feathers/issues/853