10
10
11
11
import org .elasticsearch .cluster .AbstractDiffable ;
12
12
import org .elasticsearch .cluster .Diffable ;
13
- import org .elasticsearch .common .xcontent .ParseField ;
14
13
import org .elasticsearch .common .io .stream .StreamInput ;
15
14
import org .elasticsearch .common .io .stream .StreamOutput ;
16
15
import org .elasticsearch .common .xcontent .ConstructingObjectParser ;
16
+ import org .elasticsearch .common .xcontent .ObjectParser ;
17
+ import org .elasticsearch .common .xcontent .ParseField ;
17
18
import org .elasticsearch .common .xcontent .ToXContentObject ;
18
19
import org .elasticsearch .common .xcontent .XContentBuilder ;
19
20
import org .elasticsearch .common .xcontent .XContentParser ;
21
+ import org .elasticsearch .core .Nullable ;
22
+ import org .elasticsearch .core .TimeValue ;
20
23
21
24
import java .io .IOException ;
22
25
import java .util .Locale ;
@@ -35,14 +38,16 @@ public class SingleNodeShutdownMetadata extends AbstractDiffable<SingleNodeShutd
35
38
public static final ParseField REASON_FIELD = new ParseField ("reason" );
36
39
public static final String STARTED_AT_READABLE_FIELD = "shutdown_started" ;
37
40
public static final ParseField STARTED_AT_MILLIS_FIELD = new ParseField (STARTED_AT_READABLE_FIELD + "millis" );
41
+ public static final ParseField ALLOCATION_DELAY_FIELD = new ParseField ("allocation_delay" );
38
42
39
43
public static final ConstructingObjectParser <SingleNodeShutdownMetadata , Void > PARSER = new ConstructingObjectParser <>(
40
44
"node_shutdown_info" ,
41
45
a -> new SingleNodeShutdownMetadata (
42
46
(String ) a [0 ],
43
47
Type .valueOf ((String ) a [1 ]),
44
48
(String ) a [2 ],
45
- (long ) a [3 ]
49
+ (long ) a [3 ],
50
+ (TimeValue ) a [4 ]
46
51
)
47
52
);
48
53
@@ -51,16 +56,24 @@ public class SingleNodeShutdownMetadata extends AbstractDiffable<SingleNodeShutd
51
56
PARSER .declareString (ConstructingObjectParser .constructorArg (), TYPE_FIELD );
52
57
PARSER .declareString (ConstructingObjectParser .constructorArg (), REASON_FIELD );
53
58
PARSER .declareLong (ConstructingObjectParser .constructorArg (), STARTED_AT_MILLIS_FIELD );
59
+ PARSER .declareField (
60
+ ConstructingObjectParser .optionalConstructorArg (),
61
+ (p , c ) -> TimeValue .parseTimeValue (p .textOrNull (), ALLOCATION_DELAY_FIELD .getPreferredName ()), ALLOCATION_DELAY_FIELD ,
62
+ ObjectParser .ValueType .STRING_OR_NULL
63
+ );
54
64
}
55
65
56
66
public static SingleNodeShutdownMetadata parse (XContentParser parser ) {
57
67
return PARSER .apply (parser , null );
58
68
}
59
69
70
+ public static final TimeValue DEFAULT_RESTART_SHARD_ALLOCATION_DELAY = TimeValue .timeValueMinutes (5 );
71
+
60
72
private final String nodeId ;
61
73
private final Type type ;
62
74
private final String reason ;
63
75
private final long startedAtMillis ;
76
+ @ Nullable private final TimeValue allocationDelay ;
64
77
65
78
/**
66
79
* @param nodeId The node ID that this shutdown metadata refers to.
@@ -72,19 +85,25 @@ private SingleNodeShutdownMetadata(
72
85
String nodeId ,
73
86
Type type ,
74
87
String reason ,
75
- long startedAtMillis
88
+ long startedAtMillis ,
89
+ @ Nullable TimeValue allocationDelay
76
90
) {
77
91
this .nodeId = Objects .requireNonNull (nodeId , "node ID must not be null" );
78
92
this .type = Objects .requireNonNull (type , "shutdown type must not be null" );
79
93
this .reason = Objects .requireNonNull (reason , "shutdown reason must not be null" );
80
94
this .startedAtMillis = startedAtMillis ;
95
+ if (allocationDelay != null && Type .RESTART .equals (type ) == false ) {
96
+ throw new IllegalArgumentException ("shard allocation delay is only valid for RESTART-type shutdowns" );
97
+ }
98
+ this .allocationDelay = allocationDelay ;
81
99
}
82
100
83
101
public SingleNodeShutdownMetadata (StreamInput in ) throws IOException {
84
102
this .nodeId = in .readString ();
85
103
this .type = in .readEnum (Type .class );
86
104
this .reason = in .readString ();
87
105
this .startedAtMillis = in .readVLong ();
106
+ this .allocationDelay = in .readOptionalTimeValue ();
88
107
}
89
108
90
109
/**
@@ -115,12 +134,27 @@ public long getStartedAtMillis() {
115
134
return startedAtMillis ;
116
135
}
117
136
137
+ /**
138
+ * @return The amount of time shard reallocation should be delayed for shards on this node, so that they will not be automatically
139
+ * reassigned while the node is restarting. Will be {@code null} for non-restart shutdowns.
140
+ */
141
+ @ Nullable
142
+ public TimeValue getAllocationDelay () {
143
+ if (allocationDelay != null ) {
144
+ return allocationDelay ;
145
+ } else if (Type .RESTART .equals (type )) {
146
+ return DEFAULT_RESTART_SHARD_ALLOCATION_DELAY ;
147
+ }
148
+ return null ;
149
+ }
150
+
118
151
@ Override
119
152
public void writeTo (StreamOutput out ) throws IOException {
120
153
out .writeString (nodeId );
121
154
out .writeEnum (type );
122
155
out .writeString (reason );
123
156
out .writeVLong (startedAtMillis );
157
+ out .writeOptionalTimeValue (allocationDelay );
124
158
}
125
159
126
160
@ Override
@@ -131,6 +165,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
131
165
builder .field (TYPE_FIELD .getPreferredName (), type );
132
166
builder .field (REASON_FIELD .getPreferredName (), reason );
133
167
builder .timeField (STARTED_AT_MILLIS_FIELD .getPreferredName (), STARTED_AT_READABLE_FIELD , startedAtMillis );
168
+ if (allocationDelay != null ) {
169
+ builder .field (ALLOCATION_DELAY_FIELD .getPreferredName (), allocationDelay .getStringRep ());
170
+ }
134
171
}
135
172
builder .endObject ();
136
173
@@ -145,7 +182,8 @@ public boolean equals(Object o) {
145
182
return getStartedAtMillis () == that .getStartedAtMillis ()
146
183
&& getNodeId ().equals (that .getNodeId ())
147
184
&& getType () == that .getType ()
148
- && getReason ().equals (that .getReason ());
185
+ && getReason ().equals (that .getReason ())
186
+ && Objects .equals (allocationDelay , that .allocationDelay );
149
187
}
150
188
151
189
@ Override
@@ -154,7 +192,8 @@ public int hashCode() {
154
192
getNodeId (),
155
193
getType (),
156
194
getReason (),
157
- getStartedAtMillis ()
195
+ getStartedAtMillis (),
196
+ allocationDelay
158
197
);
159
198
}
160
199
@@ -178,6 +217,7 @@ public static class Builder {
178
217
private Type type ;
179
218
private String reason ;
180
219
private long startedAtMillis = -1 ;
220
+ private TimeValue allocationDelay ;
181
221
182
222
private Builder () {}
183
223
@@ -217,15 +257,25 @@ public Builder setStartedAtMillis(long startedAtMillis) {
217
257
return this ;
218
258
}
219
259
260
+ /**
261
+ * @param allocationDelay The amount of time shard reallocation should be delayed while this node is offline.
262
+ * @return This builder.
263
+ */
264
+ public Builder setAllocationDelay (TimeValue allocationDelay ) {
265
+ this .allocationDelay = allocationDelay ;
266
+ return this ;
267
+ }
268
+
220
269
public SingleNodeShutdownMetadata build () {
221
270
if (startedAtMillis == -1 ) {
222
271
throw new IllegalArgumentException ("start timestamp must be set" );
223
272
}
273
+
224
274
return new SingleNodeShutdownMetadata (
225
275
nodeId ,
226
276
type ,
227
277
reason ,
228
- startedAtMillis
278
+ startedAtMillis , allocationDelay
229
279
);
230
280
}
231
281
}
0 commit comments