UNPKG

3.25 kBPlain TextView Raw
1/*
2 * Copyright 2019 gRPC authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18export type Deadline = Date | number;
19
20export function minDeadline(...deadlineList: Deadline[]): Deadline {
21 let minValue = Infinity;
22 for (const deadline of deadlineList) {
23 const deadlineMsecs =
24 deadline instanceof Date ? deadline.getTime() : deadline;
25 if (deadlineMsecs < minValue) {
26 minValue = deadlineMsecs;
27 }
28 }
29 return minValue;
30}
31
32const units: Array<[string, number]> = [
33 ['m', 1],
34 ['S', 1000],
35 ['M', 60 * 1000],
36 ['H', 60 * 60 * 1000],
37];
38
39export function getDeadlineTimeoutString(deadline: Deadline) {
40 const now = new Date().getTime();
41 if (deadline instanceof Date) {
42 deadline = deadline.getTime();
43 }
44 const timeoutMs = Math.max(deadline - now, 0);
45 for (const [unit, factor] of units) {
46 const amount = timeoutMs / factor;
47 if (amount < 1e8) {
48 return String(Math.ceil(amount)) + unit;
49 }
50 }
51 throw new Error('Deadline is too far in the future');
52}
53
54/**
55 * See https://nodejs.org/api/timers.html#settimeoutcallback-delay-args
56 * In particular, "When delay is larger than 2147483647 or less than 1, the
57 * delay will be set to 1. Non-integer delays are truncated to an integer."
58 * This number of milliseconds is almost 25 days.
59 */
60const MAX_TIMEOUT_TIME = 2147483647;
61
62/**
63 * Get the timeout value that should be passed to setTimeout now for the timer
64 * to end at the deadline. For any deadline before now, the timer should end
65 * immediately, represented by a value of 0. For any deadline more than
66 * MAX_TIMEOUT_TIME milliseconds in the future, a timer cannot be set that will
67 * end at that time, so it is treated as infinitely far in the future.
68 * @param deadline
69 * @returns
70 */
71export function getRelativeTimeout(deadline: Deadline) {
72 const deadlineMs = deadline instanceof Date ? deadline.getTime() : deadline;
73 const now = new Date().getTime();
74 const timeout = deadlineMs - now;
75 if (timeout < 0) {
76 return 0;
77 } else if (timeout > MAX_TIMEOUT_TIME) {
78 return Infinity;
79 } else {
80 return timeout;
81 }
82}
83
84export function deadlineToString(deadline: Deadline): string {
85 if (deadline instanceof Date) {
86 return deadline.toISOString();
87 } else {
88 const dateDeadline = new Date(deadline);
89 if (Number.isNaN(dateDeadline.getTime())) {
90 return '' + deadline;
91 } else {
92 return dateDeadline.toISOString();
93 }
94 }
95}
96
97/**
98 * Calculate the difference between two dates as a number of seconds and format
99 * it as a string.
100 * @param startDate
101 * @param endDate
102 * @returns
103 */
104export function formatDateDifference(startDate: Date, endDate: Date): string {
105 return ((endDate.getTime() - startDate.getTime()) / 1000).toFixed(3) + 's';
106}