From 960ebce016cf98596d352c292dc4caca88c952d3 Mon Sep 17 00:00:00 2001 From: Shawn Neal Date: Thu, 16 May 2024 11:32:16 -0700 Subject: [PATCH 1/2] Add health check interval --- client/process_test.go | 10 ++++++++-- resource/process.go | 11 +++++++++++ testutil/template/process.json | 7 +++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/client/process_test.go b/client/process_test.go index 7f038cc8..cd25340f 100644 --- a/client/process_test.go +++ b/client/process_test.go @@ -119,7 +119,10 @@ func TestProcesses(t *testing.T) { "health_check": { "type": "http", "data": { - "timeout": 60 + "timeout": 60, + "invocation_timeout": 5, + "interval": 10, + "endpoint": "/health" } } }`, @@ -129,7 +132,10 @@ func TestProcesses(t *testing.T) { r := resource.NewProcessUpdate(). WithCommand("rackup"). WithHealthCheckType("http"). - WithHealthCheckTimeout(60) + WithHealthCheckTimeout(60). + WithHealthCheckInterval(10). + WithHealthCheckInvocationTimeout(5). + WithHealthCheckEndpoint("/health") return c.Processes.Update(context.Background(), "ec4ff362-60c5-47a0-8246-2a134537c606", r) }, }, diff --git a/resource/process.go b/resource/process.go index 3b97b78a..646ce9bc 100644 --- a/resource/process.go +++ b/resource/process.go @@ -91,6 +91,9 @@ type ProcessData struct { // The timeout in seconds for individual health check requests for http and port health checks InvocationTimeout *int `json:"invocation_timeout,omitempty"` + // The interval in seconds between health check requests + Interval *int `json:"interval,omitempty"` + // The endpoint called to determine if the app is healthy; this key is only present for http health check Endpoint *string `json:"endpoint,omitempty"` } @@ -164,6 +167,14 @@ func (p *ProcessUpdate) WithHealthCheckInvocationTimeout(timeout int) *ProcessUp return p } +func (p *ProcessUpdate) WithHealthCheckInterval(interval int) *ProcessUpdate { + if p.HealthCheck == nil { + p.HealthCheck = &ProcessHealthCheck{} + } + p.HealthCheck.Data.Interval = &interval + return p +} + func (p *ProcessUpdate) WithHealthCheckEndpoint(endpoint string) *ProcessUpdate { if p.HealthCheck == nil { p.HealthCheck = &ProcessHealthCheck{} diff --git a/testutil/template/process.json b/testutil/template/process.json index c5da6d74..83612adc 100644 --- a/testutil/template/process.json +++ b/testutil/template/process.json @@ -7,9 +7,12 @@ "disk_in_mb": 1024, "log_rate_limit_in_bytes_per_second": 1024, "health_check": { - "type": "port", + "type": "http", "data": { - "timeout": null + "timeout": 60, + "invocation_timeout": 5, + "interval": 10, + "endpoint": "/health" } }, "relationships": { From 1b6039511e006b1aa32ef7f5f11ba7934f531f43 Mon Sep 17 00:00:00 2001 From: Shawn Neal Date: Thu, 16 May 2024 14:03:48 -0700 Subject: [PATCH 2/2] Add readiness health check --- client/process_test.go | 16 +++++++-- resource/process.go | 65 ++++++++++++++++++++++++++++++---- testutil/template/process.json | 8 +++++ 3 files changed, 80 insertions(+), 9 deletions(-) diff --git a/client/process_test.go b/client/process_test.go index cd25340f..11bade27 100644 --- a/client/process_test.go +++ b/client/process_test.go @@ -108,7 +108,7 @@ func TestProcesses(t *testing.T) { }, }, { - Description: "Update a process", + Description: "Update a process health and readiness check", Route: testutil.MockRoute{ Method: "PATCH", Endpoint: "/v3/processes/ec4ff362-60c5-47a0-8246-2a134537c606", @@ -124,6 +124,14 @@ func TestProcesses(t *testing.T) { "interval": 10, "endpoint": "/health" } + }, + "readiness_health_check": { + "type": "http", + "data": { + "invocation_timeout": 15, + "interval": 30, + "endpoint": "/ready" + } } }`, }, @@ -135,7 +143,11 @@ func TestProcesses(t *testing.T) { WithHealthCheckTimeout(60). WithHealthCheckInterval(10). WithHealthCheckInvocationTimeout(5). - WithHealthCheckEndpoint("/health") + WithHealthCheckEndpoint("/health"). + WithReadinessCheckType("http"). + WithReadinessCheckInterval(30). + WithReadinessCheckInvocationTimeout(15). + WithReadinessCheckEndpoint("/ready") return c.Processes.Update(context.Background(), "ec4ff362-60c5-47a0-8246-2a134537c606", r) }, }, diff --git a/resource/process.go b/resource/process.go index 646ce9bc..7f78e847 100644 --- a/resource/process.go +++ b/resource/process.go @@ -21,8 +21,9 @@ type Process struct { // The log rate in bytes per second allocated per instance LogRateLimitInBytesPerSecond int `json:"log_rate_limit_in_bytes_per_second"` - HealthCheck ProcessHealthCheck `json:"health_check"` - Relationships ProcessRelationships `json:"relationships"` + HealthCheck ProcessHealthCheck `json:"health_check"` + ReadinessCheck ProcessReadinessCheck `json:"readiness_health_check"` + Relationships ProcessRelationships `json:"relationships"` Metadata *Metadata `json:"metadata"` Resource `json:",inline"` @@ -36,8 +37,9 @@ type ProcessList struct { type ProcessUpdate struct { Command *string `json:"command"` - HealthCheck *ProcessHealthCheck `json:"health_check,omitempty"` - Metadata *Metadata `json:"metadata,omitempty"` + HealthCheck *ProcessHealthCheck `json:"health_check,omitempty"` + ReadinessCheck *ProcessReadinessCheck `json:"readiness_health_check,omitempty"` + Metadata *Metadata `json:"metadata,omitempty"` } type ProcessStats struct { @@ -80,11 +82,11 @@ type ProcessScale struct { type ProcessHealthCheck struct { // The type of health check to perform; valid values are http, port, and process; default is port - Type string `json:"type"` - Data ProcessData `json:"data"` + Type string `json:"type"` + Data ProcessHealthCheckData `json:"data"` } -type ProcessData struct { +type ProcessHealthCheckData struct { // The duration in seconds that health checks can fail before the process is restarted Timeout *int `json:"timeout"` @@ -98,6 +100,23 @@ type ProcessData struct { Endpoint *string `json:"endpoint,omitempty"` } +type ProcessReadinessCheck struct { + // The type of health check to perform; valid values are http, port, and process; default is process + Type string `json:"type"` + Data ProcessReadinessCheckData `json:"data"` +} + +type ProcessReadinessCheckData struct { + // The timeout in seconds for individual readiness check requests for http and port health checks + InvocationTimeout *int `json:"invocation_timeout,omitempty"` + + // The interval in seconds between readiness check requests + Interval *int `json:"interval,omitempty"` + + // The endpoint called to determine if the app is ready; this key is only present for http readiness checks + Endpoint *string `json:"endpoint,omitempty"` +} + type ProcessRelationships struct { App ToOneRelationship `json:"app"` // The app the process belongs to Revision ToOneRelationship `json:"revision"` // The app revision the process is currently running @@ -182,3 +201,35 @@ func (p *ProcessUpdate) WithHealthCheckEndpoint(endpoint string) *ProcessUpdate p.HealthCheck.Data.Endpoint = &endpoint return p } + +func (p *ProcessUpdate) WithReadinessCheckType(hcType string) *ProcessUpdate { + if p.ReadinessCheck == nil { + p.ReadinessCheck = &ProcessReadinessCheck{} + } + p.ReadinessCheck.Type = hcType + return p +} + +func (p *ProcessUpdate) WithReadinessCheckInvocationTimeout(timeout int) *ProcessUpdate { + if p.ReadinessCheck == nil { + p.ReadinessCheck = &ProcessReadinessCheck{} + } + p.ReadinessCheck.Data.InvocationTimeout = &timeout + return p +} + +func (p *ProcessUpdate) WithReadinessCheckInterval(interval int) *ProcessUpdate { + if p.ReadinessCheck == nil { + p.ReadinessCheck = &ProcessReadinessCheck{} + } + p.ReadinessCheck.Data.Interval = &interval + return p +} + +func (p *ProcessUpdate) WithReadinessCheckEndpoint(endpoint string) *ProcessUpdate { + if p.ReadinessCheck == nil { + p.ReadinessCheck = &ProcessReadinessCheck{} + } + p.ReadinessCheck.Data.Endpoint = &endpoint + return p +} diff --git a/testutil/template/process.json b/testutil/template/process.json index 83612adc..a510c30b 100644 --- a/testutil/template/process.json +++ b/testutil/template/process.json @@ -15,6 +15,14 @@ "endpoint": "/health" } }, + "readiness_health_check": { + "type": "http", + "data": { + "invocation_timeout": 15, + "interval": 30, + "endpoint": "/ready" + } + }, "relationships": { "app": { "data": {