Skip to content

Commit

Permalink
Task residency support (#301)
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrej-smola authored and timoreimann committed Aug 28, 2017
1 parent b0df019 commit dfe112d
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 0 deletions.
18 changes: 18 additions & 0 deletions application.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ type Application struct {
LastTaskFailure *LastTaskFailure `json:"lastTaskFailure,omitempty"`
Fetch *[]Fetch `json:"fetch,omitempty"`
IPAddressPerTask *IPAddressPerTask `json:"ipAddress,omitempty"`
Residency *Residency `json:"residency,omitempty"`
Secrets *map[string]Secret `json:"-"`
}

Expand Down Expand Up @@ -603,6 +604,23 @@ func (r *Application) EmptyUnreachableStrategy() *Application {
return r
}

// SetResidency sets behavior for resident applications, an application is resident when
// it has local persistent volumes set
func (r *Application) SetResidency(whenLost TaskLostBehaviorType) *Application {
r.Residency = &Residency{
TaskLostBehavior: whenLost,
}
return r
}

// EmptyResidency explicitly empties the residency -- use this if
// you need to empty the residency of an application that already has
// the residency set (setting it to nil will keep the current value).
func (r *Application) EmptyResidency() *Application {
r.Residency = &Residency{}
return r
}

// String returns the json representation of this application
func (r *Application) String() string {
s, err := json.MarshalIndent(r, "", " ")
Expand Down
4 changes: 4 additions & 0 deletions application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,10 @@ func verifyApplication(application *Application, t *testing.T) {
assert.NotNil(t, application.Tasks)
assert.Equal(t, len(*application.HealthChecks), 1)
assert.Equal(t, len(application.Tasks), 2)
assert.Equal(t, application.Residency, &Residency{
TaskLostBehavior: TaskLostBehaviorTypeRelaunchAfterTimeout,
RelaunchEscalationTimeoutSeconds: 60,
})
}

func TestApplication(t *testing.T) {
Expand Down
48 changes: 48 additions & 0 deletions residency.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright 2017 Rohith All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package marathon

import "time"

// TaskLostBehaviorType sets action taken when the resident task is lost
type TaskLostBehaviorType string

const (
// TaskLostBehaviorTypeWaitForever indicates to not take any action when the resident task is lost
TaskLostBehaviorTypeWaitForever TaskLostBehaviorType = "WAIT_FOREVER"
// TaskLostBehaviorTypeWaitForever indicates to try relaunching the lost resident task on
// another node after the relaunch escalation timeout has elapsed
TaskLostBehaviorTypeRelaunchAfterTimeout TaskLostBehaviorType = "RELAUNCH_AFTER_TIMEOUT"
)

// Residency defines how terminal states of tasks with local persistent volumes are handled
type Residency struct {
TaskLostBehavior TaskLostBehaviorType `json:"taskLostBehavior,omitempty"`
RelaunchEscalationTimeoutSeconds int `json:"relaunchEscalationTimeoutSeconds,omitempty"`
}

// SetTaskLostBehavior sets the residency behavior
func (r *Residency) SetTaskLostBehavior(behavior TaskLostBehaviorType) *Residency {
r.TaskLostBehavior = behavior
return r
}

// SetRelaunchEscalationTimeout sets the residency relaunch escalation timeout with seconds precision
func (r *Residency) SetRelaunchEscalationTimeout(timeout time.Duration) *Residency {
r.RelaunchEscalationTimeoutSeconds = int(timeout.Seconds())
return r
}
49 changes: 49 additions & 0 deletions residency_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
Copyright 2017 Rohith All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package marathon

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestResidency(t *testing.T) {
app := NewDockerApplication()

app = app.SetResidency(TaskLostBehaviorTypeWaitForever)

if assert.NotNil(t, app.Residency) {
res := app.Residency

assert.Equal(t, res.TaskLostBehavior, TaskLostBehaviorTypeWaitForever)

res.SetRelaunchEscalationTimeout(2525 * time.Millisecond)
// should be trimmed to seconds precision
assert.Equal(t, app.Residency.RelaunchEscalationTimeoutSeconds, 2)

res.SetTaskLostBehavior(TaskLostBehaviorTypeRelaunchAfterTimeout)
assert.Equal(t, res.TaskLostBehavior, TaskLostBehaviorTypeRelaunchAfterTimeout)
}

app = app.EmptyResidency()

if assert.NotNil(t, app.Residency) {
assert.Equal(t, app.Residency, &Residency{})
}
}
24 changes: 24 additions & 0 deletions tests/rest-api/methods.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
0
],
"requirePorts": false,
"residency" : {
"taskLostBehavior" : "RELAUNCH_AFTER_TIMEOUT",
"relaunchEscalationTimeoutSeconds" : 60
},
"storeUrls": [],
"upgradeStrategy": {
"minimumHealthCapacity": 0.5,
Expand Down Expand Up @@ -201,6 +205,10 @@
10001
],
"requirePorts": false,
"residency" : {
"taskLostBehavior" : "RELAUNCH_AFTER_TIMEOUT",
"relaunchEscalationTimeoutSeconds" : 60
},
"storeUrls": [],
"tasksRunning": 2,
"tasksStaged": 0,
Expand Down Expand Up @@ -353,6 +361,10 @@
10000
],
"requirePorts": false,
"residency" : {
"taskLostBehavior" : "RELAUNCH_AFTER_TIMEOUT",
"relaunchEscalationTimeoutSeconds" : 60
},
"storeUrls": [],
"tasks": [
{
Expand Down Expand Up @@ -469,6 +481,10 @@
10000
],
"requirePorts": false,
"residency" : {
"taskLostBehavior" : "RELAUNCH_AFTER_TIMEOUT",
"relaunchEscalationTimeoutSeconds" : 60
},
"storeUrls": [],
"tasks": [
{
Expand Down Expand Up @@ -598,6 +614,10 @@
10000
],
"requirePorts": false,
"residency" : {
"taskLostBehavior" : "RELAUNCH_AFTER_TIMEOUT",
"relaunchEscalationTimeoutSeconds" : 60
},
"storeUrls": [],
"tasks": [
{
Expand Down Expand Up @@ -1248,6 +1268,10 @@
10001
],
"requirePorts": false,
"residency" : {
"taskLostBehavior" : "RELAUNCH_AFTER_TIMEOUT",
"relaunchEscalationTimeoutSeconds" : 60
},
"storeUrls": [],
"tasksRunning": 2,
"tasksStaged": 0,
Expand Down

0 comments on commit dfe112d

Please sign in to comment.