Marshals a nanoseconds representation of the timeout to and from a string representation, consisting of an ASCII decimal representation of a number with at most 8 digits, followed by a unit. Available units: n = nanoseconds u = microseconds m = milliseconds S = seconds M = minutes H = hours The
| 654 | * request header definition</a></p> |
| 655 | */ |
| 656 | @VisibleForTesting |
| 657 | static class TimeoutMarshaller implements Metadata.AsciiMarshaller<Long> { |
| 658 | |
| 659 | @Override |
| 660 | public String toAsciiString(Long timeoutNanosObject) { |
| 661 | long cutoff = 100000000; |
| 662 | // Timeout checking is inherently racy. RPCs with timeouts in the past ideally don't even get |
| 663 | // here, but if the timeout is expired assume that happened recently and adjust it to the |
| 664 | // smallest allowed timeout |
| 665 | long timeoutNanos = Math.max(1, timeoutNanosObject); |
| 666 | TimeUnit unit = TimeUnit.NANOSECONDS; |
| 667 | if (timeoutNanos < cutoff) { |
| 668 | return timeoutNanos + "n"; |
| 669 | } else if (timeoutNanos < cutoff * 1000L) { |
| 670 | return unit.toMicros(timeoutNanos) + "u"; |
| 671 | } else if (timeoutNanos < cutoff * 1000L * 1000L) { |
| 672 | return unit.toMillis(timeoutNanos) + "m"; |
| 673 | } else if (timeoutNanos < cutoff * 1000L * 1000L * 1000L) { |
| 674 | return unit.toSeconds(timeoutNanos) + "S"; |
| 675 | } else if (timeoutNanos < cutoff * 1000L * 1000L * 1000L * 60L) { |
| 676 | return unit.toMinutes(timeoutNanos) + "M"; |
| 677 | } else { |
| 678 | return unit.toHours(timeoutNanos) + "H"; |
| 679 | } |
| 680 | } |
| 681 | |
| 682 | @Override |
| 683 | public Long parseAsciiString(String serialized) { |
| 684 | checkArgument(serialized.length() > 0, "empty timeout"); |
| 685 | checkArgument(serialized.length() <= 9, "bad timeout format"); |
| 686 | long value = Long.parseLong(serialized.substring(0, serialized.length() - 1)); |
| 687 | char unit = serialized.charAt(serialized.length() - 1); |
| 688 | switch (unit) { |
| 689 | case 'n': |
| 690 | return value; |
| 691 | case 'u': |
| 692 | return TimeUnit.MICROSECONDS.toNanos(value); |
| 693 | case 'm': |
| 694 | return TimeUnit.MILLISECONDS.toNanos(value); |
| 695 | case 'S': |
| 696 | return TimeUnit.SECONDS.toNanos(value); |
| 697 | case 'M': |
| 698 | return TimeUnit.MINUTES.toNanos(value); |
| 699 | case 'H': |
| 700 | return TimeUnit.HOURS.toNanos(value); |
| 701 | default: |
| 702 | throw new IllegalArgumentException(String.format("Invalid timeout unit: %s", unit)); |
| 703 | } |
| 704 | } |
| 705 | } |
| 706 | |
| 707 | /** |
| 708 | * Returns a transport out of a PickResult, or {@code null} if the result is "buffer". |
nothing calls this directly
no outgoing calls
no test coverage detected