Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CF app readiness checks #411

Merged
merged 2 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions client/process_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -119,7 +119,18 @@ func TestProcesses(t *testing.T) {
"health_check": {
"type": "http",
"data": {
"timeout": 60
"timeout": 60,
"invocation_timeout": 5,
"interval": 10,
"endpoint": "/health"
}
},
"readiness_health_check": {
"type": "http",
"data": {
"invocation_timeout": 15,
"interval": 30,
"endpoint": "/ready"
}
}
}`,
Expand All @@ -129,7 +140,14 @@ func TestProcesses(t *testing.T) {
r := resource.NewProcessUpdate().
WithCommand("rackup").
WithHealthCheckType("http").
WithHealthCheckTimeout(60)
WithHealthCheckTimeout(60).
WithHealthCheckInterval(10).
WithHealthCheckInvocationTimeout(5).
WithHealthCheckEndpoint("/health").
WithReadinessCheckType("http").
WithReadinessCheckInterval(30).
WithReadinessCheckInvocationTimeout(15).
WithReadinessCheckEndpoint("/ready")
return c.Processes.Update(context.Background(), "ec4ff362-60c5-47a0-8246-2a134537c606", r)
},
},
Expand Down
76 changes: 69 additions & 7 deletions resource/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand All @@ -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 {
Expand Down Expand Up @@ -80,21 +82,41 @@ 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"`

// 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"`
}

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
Expand Down Expand Up @@ -164,10 +186,50 @@ 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{}
}
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
}
15 changes: 13 additions & 2 deletions testutil/template/process.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,20 @@
"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"
}
},
"readiness_health_check": {
"type": "http",
"data": {
"invocation_timeout": 15,
"interval": 30,
"endpoint": "/ready"
}
},
"relationships": {
Expand Down
Loading