Feat: Add http/http keyword timeout option (#2142)

* feat: Add timeoutMs field

* chore: Update Languages (incl. ko-KR)

* Revert "chore: Update Languages (incl. ko-KR)"

This reverts commit 349331a00b.

* chore: Update ko-KR selectively

* chore: Update en selectively

* Merge manually

* Reorder and show only if http related monitors

* fix: Update Korean translation

* fix: Rename timeoutMs to timeout, rename label, make DOUBLE

* fix: Change minimum step to 0.1, matching DOUBLE type

* Put the sql patch at the end

* Update EditMonitor.vue

* Colocate timeout with retry, fix clampTimeout logic, show default on 0

* Update src/pages/EditMonitor.vue to remove a comment

Co-authored-by: Frank Elsinga <frank@elsinga.de>

* Fix merge issue

* Update the timeout value while finished editing the interval value

---------

Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
Co-authored-by: Frank Elsinga <frank@elsinga.de>
This commit is contained in:
Jinhyeok Lee
2023-08-07 01:14:56 +09:00
committed by GitHub
parent c6e68fac97
commit 439b6517d1
7 changed files with 56 additions and 4 deletions

View File

@@ -59,6 +59,8 @@
"Hostname": "Hostname",
"Port": "Port",
"Heartbeat Interval": "Heartbeat Interval",
"Request Timeout": "Request Timeout",
"timeoutAfter": "Timeout after {0} seconds",
"Retries": "Retries",
"Heartbeat Retry Interval": "Heartbeat Retry Interval",
"Resend Notification if Down X times consecutively": "Resend Notification if Down X times consecutively",

View File

@@ -589,6 +589,8 @@
"RadiusCalledStationIdDescription": "접속 스테이션의 식별자",
"RadiusCallingStationId": "접속 요청 스테이션의 Id",
"RadiusCallingStationIdDescription": "접속 요청 스테이션의 식별자",
"timeoutAfter": "{0}초 후 타임아웃",
"Request Timeout": "요청 타임아웃",
"Query": "쿼리",
"settingsCertificateExpiry": "TLS 인증서 만료",
"certificationExpiryDescription": "HTTPS 모니터링 TLS 인증서가 만료되면 알림을 활성화해요:",

View File

@@ -393,7 +393,7 @@
<!-- Interval -->
<div class="my-3">
<label for="interval" class="form-label">{{ $t("Heartbeat Interval") }} ({{ $t("checkEverySecond", [ monitor.interval ]) }})</label>
<input id="interval" v-model="monitor.interval" type="number" class="form-control" required :min="minInterval" step="1" :max="maxInterval">
<input id="interval" v-model="monitor.interval" type="number" class="form-control" required :min="minInterval" step="1" :max="maxInterval" @blur="finishUpdateInterval">
</div>
<div class="my-3">
@@ -412,6 +412,12 @@
<input id="retry-interval" v-model="monitor.retryInterval" type="number" class="form-control" required :min="minInterval" step="1">
</div>
<!-- Timeout: HTTP / Keyword only -->
<div v-if="monitor.type === 'http' || monitor.type === 'keyword'" class="my-3">
<label for="timeout" class="form-label">{{ $t("Request Timeout") }} ({{ $t("timeoutAfter", [ monitor.timeout || clampTimeout(monitor.interval) ]) }})</label>
<input id="timeout" v-model="monitor.timeout" type="number" class="form-control" required min="0" step="0.1">
</div>
<div class="my-3">
<label for="resend-interval" class="form-label">
{{ $t("Resend Notification if Down X times consecutively") }}
@@ -840,6 +846,7 @@ const monitorDefaults = {
retryInterval: 60,
resendInterval: 0,
maxretries: 1,
timeout: 48,
notificationIDList: {},
ignoreTls: false,
upsideDown: false,
@@ -1113,6 +1120,13 @@ message HealthCheckResponse {
}
},
"monitor.timeout"(value, oldValue) {
// keep timeout within 80% range
if (value && value !== oldValue) {
this.monitor.timeout = this.clampTimeout(value);
}
},
"monitor.type"() {
if (this.monitor.type === "push") {
if (! this.monitor.pushToken) {
@@ -1274,6 +1288,10 @@ message HealthCheckResponse {
if (this.monitor.retryInterval === 0) {
this.monitor.retryInterval = this.monitor.interval;
}
// Handling for monitors that are missing/zeroed timeout
if (!this.monitor.timeout) {
this.monitor.timeout = ~~(this.monitor.interval * 8) / 10;
}
} else {
toast.error(res.msg);
}
@@ -1445,7 +1463,26 @@ message HealthCheckResponse {
addedDraftGroup(draftGroupName) {
this.draftGroupName = draftGroupName;
this.monitor.parent = -1;
}
},
// Clamp timeout
clampTimeout(timeout) {
// limit to 80% of interval, narrowly avoiding epsilon bug
const maxTimeout = ~~(this.monitor.interval * 8 ) / 10;
const clamped = Math.max(0, Math.min(timeout, maxTimeout));
// 0 will be treated as 80% of interval
return Number.isFinite(clamped) ? clamped : maxTimeout;
},
finishUpdateInterval() {
// Update timeout if it is greater than the clamp timeout
let clampedValue = this.clampTimeout(this.monitor.interval);
if (this.monitor.timeout > clampedValue) {
this.monitor.timeout = clampedValue;
}
},
},
};
</script>