-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
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
Simplify persistence design for temporarily offline status #9855
base: master
Are you sure you want to change the base?
Changes from all commits
187a823
962a286
888103c
0d129d9
1d20b1c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -179,11 +179,6 @@ | |||||||
|
||||||||
private long connectTime = 0; | ||||||||
|
||||||||
/** | ||||||||
* True if Jenkins shouldn't start new builds on this node. | ||||||||
*/ | ||||||||
private boolean temporarilyOffline; | ||||||||
|
||||||||
/** | ||||||||
* {@link Node} object may be created and deleted independently | ||||||||
* from this object. | ||||||||
|
@@ -360,7 +355,8 @@ | |||||||
*/ | ||||||||
@Exported | ||||||||
public OfflineCause getOfflineCause() { | ||||||||
return offlineCause; | ||||||||
var temporaryOfflineCause = getNodeOrDie().getTemporaryOfflineCause(); | ||||||||
return temporaryOfflineCause == null ? offlineCause : temporaryOfflineCause; | ||||||||
} | ||||||||
|
||||||||
@Override | ||||||||
|
@@ -549,7 +545,7 @@ | |||||||
@Deprecated | ||||||||
public void cliOffline(String cause) throws ExecutionException, InterruptedException { | ||||||||
checkPermission(DISCONNECT); | ||||||||
setTemporarilyOffline(true, new ByCLI(cause)); | ||||||||
setTemporarilyOfflineCause(new ByCLI(cause)); | ||||||||
} | ||||||||
|
||||||||
/** | ||||||||
|
@@ -558,7 +554,7 @@ | |||||||
@Deprecated | ||||||||
public void cliOnline() throws ExecutionException, InterruptedException { | ||||||||
checkPermission(CONNECT); | ||||||||
setTemporarilyOffline(false, null); | ||||||||
setTemporarilyOfflineCause(null); | ||||||||
} | ||||||||
|
||||||||
/** | ||||||||
|
@@ -606,6 +602,15 @@ | |||||||
return j.getNode(nodeName); | ||||||||
} | ||||||||
|
||||||||
@NonNull | ||||||||
private Node getNodeOrDie() { | ||||||||
var node = nodeName == null ? Jenkins.get() : Jenkins.get().getNode(nodeName); | ||||||||
if (node == null) { | ||||||||
throw new IllegalStateException("Can't set a temporary offline cause if the node has been removed"); | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this nullness check needs to be moved up into the callers, since some are just reading the status, not trying to set it, right? |
||||||||
} | ||||||||
return node; | ||||||||
} | ||||||||
|
||||||||
@Exported | ||||||||
public LoadStatistics getLoadStatistics() { | ||||||||
return LabelAtom.get(nodeName != null ? nodeName : Jenkins.get().getSelfLabel().toString()).loadStatistics; | ||||||||
|
@@ -620,7 +625,7 @@ | |||||||
@Exported | ||||||||
@Override | ||||||||
public boolean isOffline() { | ||||||||
return temporarilyOffline || getChannel() == null; | ||||||||
return getNodeOrDie().isTemporarilyOffline() || getChannel() == null; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For example this will throw an ISE from the whole
Suggested change
|
||||||||
} | ||||||||
|
||||||||
public final boolean isOnline() { | ||||||||
|
@@ -669,43 +674,46 @@ | |||||||
@Exported | ||||||||
@Deprecated | ||||||||
public boolean isTemporarilyOffline() { | ||||||||
return temporarilyOffline; | ||||||||
return getNodeOrDie().isTemporarilyOffline(); | ||||||||
} | ||||||||
|
||||||||
/** | ||||||||
* @deprecated as of 1.320. | ||||||||
* Use {@link #setTemporarilyOffline(boolean, OfflineCause)} | ||||||||
* Use {@link #setTemporarilyOfflineCause(OfflineCause)} | ||||||||
*/ | ||||||||
@Deprecated | ||||||||
public void setTemporarilyOffline(boolean temporarilyOffline) { | ||||||||
setTemporarilyOffline(temporarilyOffline, null); | ||||||||
setTemporarilyOfflineCause(temporarilyOffline ? new OfflineCause.LegacyOfflineCause() : null); | ||||||||
} | ||||||||
|
||||||||
/** | ||||||||
* Marks the computer as temporarily offline. This retains the underlying | ||||||||
* {@link Channel} connection, but prevent builds from executing. | ||||||||
* | ||||||||
* @param cause | ||||||||
* If the first argument is true, specify the reason why the node is being put | ||||||||
* offline. | ||||||||
* @deprecated as of TODO. | ||||||||
* Use {@link #setTemporarilyOfflineCause(OfflineCause)} instead. | ||||||||
*/ | ||||||||
@Deprecated | ||||||||
public void setTemporarilyOffline(boolean temporarilyOffline, OfflineCause cause) { | ||||||||
offlineCause = temporarilyOffline ? cause : null; | ||||||||
this.temporarilyOffline = temporarilyOffline; | ||||||||
Node node = getNode(); | ||||||||
if (node != null) { | ||||||||
node.setTemporaryOfflineCause(offlineCause); | ||||||||
} | ||||||||
synchronized (statusChangeLock) { | ||||||||
statusChangeLock.notifyAll(); | ||||||||
} | ||||||||
if (temporarilyOffline) { | ||||||||
Listeners.notify(ComputerListener.class, false, l -> l.onTemporarilyOffline(this, cause)); | ||||||||
if (cause == null) { | ||||||||
setTemporarilyOffline(temporarilyOffline); | ||||||||
} else { | ||||||||
Listeners.notify(ComputerListener.class, false, l -> l.onTemporarilyOnline(this)); | ||||||||
setTemporarilyOfflineCause(cause); | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
/** | ||||||||
* Marks the computer as temporarily offline. This retains the underlying | ||||||||
* {@link Channel} connection, but prevent builds from executing. | ||||||||
* | ||||||||
* @param temporarilyOfflineCause The reason why the node is being put offline. | ||||||||
* If null, this cancels the status | ||||||||
*/ | ||||||||
public void setTemporarilyOfflineCause(@CheckForNull OfflineCause temporarilyOfflineCause) { | ||||||||
getNodeOrDie().setTemporaryOfflineCause(temporarilyOfflineCause); | ||||||||
} | ||||||||
|
||||||||
public OfflineCause getTemporarilyOfflineCause() { | ||||||||
return getNodeOrDie().getTemporaryOfflineCause(); | ||||||||
} | ||||||||
|
||||||||
@Exported | ||||||||
@Override | ||||||||
public String getIcon() { | ||||||||
|
@@ -785,16 +793,6 @@ | |||||||
this.nodeName = null; | ||||||||
|
||||||||
setNumExecutors(node.getNumExecutors()); | ||||||||
if (this.temporarilyOffline) { | ||||||||
// When we get a new node, push our current temp offline | ||||||||
// status to it (as the status is not carried across | ||||||||
// configuration changes that recreate the node). | ||||||||
// Since this is also called the very first time this | ||||||||
// Computer is created, avoid pushing an empty status | ||||||||
// as that could overwrite any status that the Node | ||||||||
// brought along from its persisted config data. | ||||||||
node.setTemporaryOfflineCause(this.offlineCause); | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
/** | ||||||||
|
@@ -1396,24 +1394,19 @@ | |||||||
|
||||||||
@RequirePOST | ||||||||
public HttpResponse doToggleOffline(@QueryParameter String offlineMessage) throws IOException, ServletException { | ||||||||
if (!temporarilyOffline) { | ||||||||
checkPermission(DISCONNECT); | ||||||||
offlineMessage = Util.fixEmptyAndTrim(offlineMessage); | ||||||||
setTemporarilyOffline(!temporarilyOffline, | ||||||||
new OfflineCause.UserCause(User.current(), offlineMessage)); | ||||||||
} else { | ||||||||
if (getNodeOrDie().isTemporarilyOffline()) { | ||||||||
checkPermission(CONNECT); | ||||||||
setTemporarilyOffline(!temporarilyOffline, null); | ||||||||
setTemporarilyOfflineCause(null); | ||||||||
return HttpResponses.redirectToDot(); | ||||||||
} else { | ||||||||
return doChangeOfflineCause(offlineMessage); | ||||||||
} | ||||||||
return HttpResponses.redirectToDot(); | ||||||||
} | ||||||||
|
||||||||
@RequirePOST | ||||||||
public HttpResponse doChangeOfflineCause(@QueryParameter String offlineMessage) throws IOException, ServletException { | ||||||||
checkPermission(DISCONNECT); | ||||||||
offlineMessage = Util.fixEmptyAndTrim(offlineMessage); | ||||||||
setTemporarilyOffline(true, | ||||||||
new OfflineCause.UserCause(User.current(), offlineMessage)); | ||||||||
setTemporarilyOfflineCause(new OfflineCause.UserCause(User.current(), Util.fixEmptyAndTrim(offlineMessage))); | ||||||||
return HttpResponses.redirectToDot(); | ||||||||
} | ||||||||
|
||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Retaining previous behaviour : if a temporary offline cause is defined, from outside PoV, it replaces the technical offline cause.