An end-to-end gRPC deadline is an absolute point in time, not a fresh timeout for every service. Passing a new generous timeout at each hop can let downstream work continue after the original caller has already given up.
Design a GrpcDeadlinePropagator class:
GrpcDeadlinePropagator() creates a stateless planner.int[] propagate(int startTime, int clientTimeout, int[] processingTimes, int[] localTimeouts) returns the absolute deadline forwarded at every downstream hop.
The original deadline is startTime + clientTimeout. Let now initially equal startTime. For hop i:
- Add
processingTimes[i] to now; this is time already spent before making the downstream call. - If
now >= inheritedDeadline, append -1 for this hop and every remaining hop. - Otherwise, the child deadline is
min(inheritedDeadline, now + localTimeouts[i]). - Append that absolute deadline and use it as the inherited deadline for the next hop.
A local policy may shorten a deadline but may never extend its parent. Do not mutate either input array, and keep repeated calls independent.
Example 1:
Input:
Output:
Explanation: Time already spent affects each local bound, and no child deadline exceeds its parent.
Example 2:
Input:
Output:
Explanation: The second hop reaches the inherited deadline exactly, so it and every deeper call are cancelled.
Constraints
0 <= startTime, clientTimeout <= 10^90 <= processingTimes.length == localTimeouts.length <= 10^40 <= processingTimes[i] <= 10^91 <= localTimeouts[i] <= 10^9- All intermediate sums fit a signed 32-bit integer.
- At most
100 calls are made to propagate.