重试链
如果由于网络或服务器错误而失败,尝试多次执行操作。
概述
@apollo/client/link/retry
可用于在一定次数内重试操作。操作这在处理不可靠的通信情况时很有用,你可能宁愿等待时间更长,而不是明确定义操作失败。@apollo/client/link/retry
默认提供指数退避,并默认在尝试之间抖动延迟。
一个示例用例是在网络连接离线时保持请求,并在上线后重试。
import { RetryLink } from "@apollo/client/link/retry";const link = new RetryLink();
选项
The standard retry strategy provides exponential backoff with jittering, and takes the following options, grouped into delay
and attempt
strategies:
options.delay
Option | Description |
---|---|
delay.initial | The number of milliseconds to wait before attempting the first retry. |
delay.max | The maximum number of milliseconds that the link should wait for any retry. |
delay.jitter | Whether delays between attempts should be randomized. |
options.attempts
Option | Description |
---|---|
attempts.max | The max number of times to try a single operation before giving up. |
attempts.retryIf | A predicate function that can determine whether a particular response should be retried. |
Default configuration
The default configuration is equivalent to
new RetryLink({delay: {initial: 300,max: Infinity,jitter: true},attempts: {max: 5,retryIf: (error, _operation) => !!error}});
Avoiding thundering herd
Starting with initialDelay
, the delay of each subsequent retry is increased exponentially, meaning it's multiplied by 2 each time. For example, if initialDelay
is 100, additional retries will occur after delays of 200, 400, 800, etc.
With the jitter
option enabled, delays are randomized anywhere between 0ms (instant), and 2x the configured delay. This way you get the same result on average, but with random delays.
这两个功能结合使用,有助于缓解 thundering herd 问题,通过在主要停电期间分配负载来实现。如果没有这些策略,当服务器恢复正常时,它将一次性被所有客户端击中,这可能导致它再次出现故障。
自定义策略
您可以为delay
和/或attempts
传递一个函数,这些函数实现了针对每个的定制策略。在两种情况下,函数都提供了相同的参数(count
、operation
、error
)。
attempts
函数应返回一个boolean
(或一个解析为boolean
的Promise
)来表示是否应该重试响应。如果是,则会调用delay
函数,并应返回要延迟的毫秒数。
import { RetryLink } from "@apollo/client/link/retry";const link = new RetryLink({attempts: (count, operation, error) => {return !!error && operation.operationName != 'specialCase';},delay: (count, operation, error) => {return count * 1000 * Math.random();},});