1818package org .apache .ignite .internal .processors .rollingupgrade ;
1919
2020import java .util .Objects ;
21+ import java .util .UUID ;
2122import java .util .concurrent .CountDownLatch ;
2223import org .apache .ignite .IgniteCheckedException ;
2324import org .apache .ignite .IgniteException ;
2425import org .apache .ignite .cluster .ClusterNode ;
26+ import org .apache .ignite .events .DiscoveryEvent ;
27+ import org .apache .ignite .events .Event ;
2528import org .apache .ignite .internal .GridKernalContext ;
29+ import org .apache .ignite .internal .managers .eventstorage .GridLocalEventListener ;
2630import org .apache .ignite .internal .processors .GridProcessorAdapter ;
2731import org .apache .ignite .internal .processors .metastorage .DistributedMetaStorage ;
2832import org .apache .ignite .internal .processors .metastorage .DistributedMetastorageLifecycleListener ;
4044import org .apache .ignite .spi .discovery .tcp .internal .TcpDiscoveryNodesRing ;
4145import org .jetbrains .annotations .Nullable ;
4246
47+ import static org .apache .ignite .events .EventType .EVT_NODE_FAILED ;
48+ import static org .apache .ignite .events .EventType .EVT_NODE_JOINED ;
49+ import static org .apache .ignite .events .EventType .EVT_NODE_LEFT ;
4350import static org .apache .ignite .internal .IgniteNodeAttributes .ATTR_BUILD_VER ;
4451import static org .apache .ignite .internal .processors .metastorage .DistributedMetaStorage .IGNITE_INTERNAL_KEY_PREFIX ;
4552
@@ -88,6 +95,17 @@ public RollingUpgradeProcessor(GridKernalContext ctx) {
8895
8996 /** {@inheritDoc} */
9097 @ Override public void start () throws IgniteCheckedException {
98+ ctx .event ().addLocalEventListener (new GridLocalEventListener () {
99+ @ Override public void onEvent (Event evt ) {
100+ UUID nodeId = ((DiscoveryEvent )evt ).eventNode ().id ();
101+
102+ synchronized (lock ) {
103+ if (lastJoiningNode != null && lastJoiningNode .id ().equals (nodeId ))
104+ lastJoiningNode = null ;
105+ }
106+ }
107+ }, EVT_NODE_JOINED , EVT_NODE_FAILED , EVT_NODE_LEFT );
108+
91109 ctx .internalSubscriptionProcessor ().registerDistributedMetastorageListener (new DistributedMetastorageLifecycleListener () {
92110 @ Override public void onReadyForWrite (DistributedMetaStorage metastorage ) {
93111 RollingUpgradeProcessor .this .metastorage = metastorage ;
@@ -212,6 +230,8 @@ public void enable(IgniteProductVersion target, boolean force) throws IgniteChec
212230 * Disables rolling upgrade.
213231 * This method can only be called on coordinator node.
214232 *
233+ * <p>May be blocked while a node with a different version is still joining or during metastorage operations.</p>
234+ *
215235 * @throws IgniteCheckedException If cluster has two or more nodes with different versions or if node is not coordinator
216236 * or metastorage is not ready.
217237 */
@@ -235,6 +255,8 @@ public void disable() throws IgniteCheckedException {
235255
236256 synchronized (lock ) {
237257 if (lastJoiningNode != null ) {
258+ // Use 3 * joinTimeout as an upper time bound for joining nodes that may drop during validation
259+ // without sending NODE_LEFT / NODE_FAILED events.
238260 long timeout = ((TcpDiscoverySpi )ctx .config ().getDiscoverySpi ()).getJoinTimeout () * 3 ;
239261
240262 if (ring .node (lastJoiningNode .id ()) != null || (timeout > 0 && U .currentTimeMillis () - lastJoiningNodeTimestamp > timeout ))
0 commit comments