コード例 #1
0
  /** @param nodeId Left node id. */
  public void onNodeLeft(final UUID nodeId) {
    if (isDone()) return;

    if (!enterBusy()) return;

    try {
      // Wait for initialization part of this future to complete.
      initFut.listen(
          new CI1<IgniteInternalFuture<?>>() {
            @Override
            public void apply(IgniteInternalFuture<?> f) {
              if (isDone()) return;

              if (!enterBusy()) return;

              try {
                // Pretend to have received message from this node.
                rcvdIds.add(nodeId);

                Collection<UUID> rmtIds = GridDhtPartitionsExchangeFuture.this.rmtIds;

                assert rmtIds != null;

                ClusterNode oldest = oldestNode.get();

                if (oldest.id().equals(nodeId)) {
                  if (log.isDebugEnabled())
                    log.debug(
                        "Oldest node left or failed on partition exchange "
                            + "(will restart exchange process)) [oldestNodeId="
                            + oldest.id()
                            + ", exchangeId="
                            + exchId
                            + ']');

                  boolean set = false;

                  ClusterNode newOldest =
                      CU.oldestAliveCacheServerNode(cctx, exchId.topologyVersion());

                  if (newOldest != null) {
                    // If local node is now oldest.
                    if (newOldest.id().equals(cctx.localNodeId())) {
                      synchronized (mux) {
                        if (oldestNode.compareAndSet(oldest, newOldest)) {
                          // If local node is just joining.
                          if (exchId.nodeId().equals(cctx.localNodeId())) {
                            try {
                              for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
                                if (!cacheCtx.isLocal())
                                  cacheCtx
                                      .topology()
                                      .beforeExchange(GridDhtPartitionsExchangeFuture.this);
                              }
                            } catch (IgniteCheckedException e) {
                              onDone(e);

                              return;
                            }
                          }

                          set = true;
                        }
                      }
                    } else {
                      synchronized (mux) {
                        set = oldestNode.compareAndSet(oldest, newOldest);
                      }

                      if (set && log.isDebugEnabled())
                        log.debug(
                            "Reassigned oldest node [this="
                                + cctx.localNodeId()
                                + ", old="
                                + oldest.id()
                                + ", new="
                                + newOldest.id()
                                + ']');
                    }
                  }

                  if (set) {
                    // If received any messages, process them.
                    for (Map.Entry<UUID, GridDhtPartitionsSingleMessage> m : singleMsgs.entrySet())
                      onReceive(m.getKey(), m.getValue());

                    for (Map.Entry<UUID, GridDhtPartitionsFullMessage> m : fullMsgs.entrySet())
                      onReceive(m.getKey(), m.getValue());

                    // Reassign oldest node and resend.
                    recheck();
                  }
                } else if (rmtIds.contains(nodeId)) {
                  if (log.isDebugEnabled())
                    log.debug(
                        "Remote node left of failed during partition exchange (will ignore) "
                            + "[rmtNode="
                            + nodeId
                            + ", exchangeId="
                            + exchId
                            + ']');

                  assert rmtNodes != null;

                  for (Iterator<ClusterNode> it = rmtNodes.iterator(); it.hasNext(); ) {
                    if (it.next().id().equals(nodeId)) it.remove();
                  }

                  if (allReceived() && ready.get() && replied.compareAndSet(false, true))
                    if (spreadPartitions()) onDone(exchId.topologyVersion());
                }
              } finally {
                leaveBusy();
              }
            }
          });
    } finally {
      leaveBusy();
    }
  }