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

api: add StartedAt in Node.DrainStrategy #6698

Merged
merged 2 commits into from
Nov 15, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions api/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,9 @@ type DrainStrategy struct {
// ForceDeadline is the deadline time for the drain after which drains will
// be forced
ForceDeadline time.Time

// StartedAt is the time the drain process started
StartedAt time.Time
}

// DrainSpec describes a Node's drain behavior.
Expand Down
11 changes: 10 additions & 1 deletion nomad/node_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,9 +536,18 @@ func (n *Node) UpdateDrain(args *structs.NodeUpdateDrainRequest,
}
}

// Mark start time for the drain
if args.DrainStrategy != nil {
if node.DrainStrategy == nil || node.DrainStrategy.StartedAt.IsZero() {
args.DrainStrategy.StartedAt = time.Now().UTC()
} else {
args.DrainStrategy.StartedAt = node.DrainStrategy.StartedAt
}
}

// Mark the deadline time
if args.DrainStrategy != nil && args.DrainStrategy.Deadline.Nanoseconds() > 0 {
args.DrainStrategy.ForceDeadline = time.Now().Add(args.DrainStrategy.Deadline)
args.DrainStrategy.ForceDeadline = time.Now().Add(args.DrainStrategy.Deadline).UTC()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like @jrasell's idea of having a var startedAt time that we could then use here as well to add on to. There seems to be at least one more location calling time.Now that could also benefit from using a shared variable

}

// Construct the node event
Expand Down
17 changes: 14 additions & 3 deletions nomad/node_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,17 @@ func TestClientEndpoint_UpdateDrain(t *testing.T) {
// now+deadline should be after the forced deadline
require.True(time.Now().Add(strategy.Deadline).After(out.DrainStrategy.ForceDeadline))

drainStartedAt := out.DrainStrategy.StartedAt
// StartedAt should be close to the time the drain started
require.WithinDuration(beforeUpdate, out.DrainStrategy.StartedAt, 1*time.Second)

// StartedAt shouldn't change if a new request comes while still draining
require.Nil(msgpackrpc.CallWithCodec(codec, "Node.UpdateDrain", dereg, &resp2))
ws = memdb.NewWatchSet()
out, err = state.NodeByID(ws, node.ID)
require.NoError(err)
require.True(out.DrainStrategy.StartedAt.Equal(drainStartedAt))

// Register a system job
job := mock.SystemJob()
require.Nil(s1.State().UpsertJob(10, job))
Expand All @@ -923,16 +934,16 @@ func TestClientEndpoint_UpdateDrain(t *testing.T) {
ws = memdb.NewWatchSet()
out, err = state.NodeByID(ws, node.ID)
require.NoError(err)
require.Len(out.Events, 3)
require.Equal(NodeDrainEventDrainDisabled, out.Events[2].Message)
require.Len(out.Events, 4)
require.Equal(NodeDrainEventDrainDisabled, out.Events[3].Message)

// Check that calling UpdateDrain with the same DrainStrategy does not emit
// a node event.
require.Nil(msgpackrpc.CallWithCodec(codec, "Node.UpdateDrain", dereg, &resp3))
ws = memdb.NewWatchSet()
out, err = state.NodeByID(ws, node.ID)
require.NoError(err)
require.Len(out.Events, 3)
require.Len(out.Events, 4)
}

func TestClientEndpoint_UpdateDrain_ACL(t *testing.T) {
Expand Down
3 changes: 3 additions & 0 deletions nomad/structs/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1445,6 +1445,9 @@ type DrainStrategy struct {
// ForceDeadline is the deadline time for the drain after which drains will
// be forced
ForceDeadline time.Time

// StartedAt is the time the drain process started
StartedAt time.Time
}

func (d *DrainStrategy) Copy() *DrainStrategy {
Expand Down