コード例 #1
0
ファイル: GridNearTxRemote.java プロジェクト: Reamy/ignite
  /**
   * @param entry Entry to enlist.
   * @throws IgniteCheckedException If failed.
   * @return {@code True} if entry was enlisted.
   */
  private boolean addEntry(IgniteTxEntry entry) throws IgniteCheckedException {
    checkInternal(entry.txKey());

    GridCacheContext cacheCtx = entry.context();

    if (!cacheCtx.isNear()) cacheCtx = cacheCtx.dht().near().context();

    GridNearCacheEntry cached = cacheCtx.near().peekExx(entry.key());

    if (cached == null) {
      evicted.add(entry.txKey());

      return false;
    } else {
      try {
        cached.unswap();

        CacheObject val = cached.peek(true, false, false, null);

        if (val == null && cached.evictInternal(false, xidVer, null)) {
          evicted.add(entry.txKey());

          return false;
        } else {
          // Initialize cache entry.
          entry.cached(cached);

          txState.addWriteEntry(entry.txKey(), entry);

          addExplicit(entry);

          return true;
        }
      } catch (GridCacheEntryRemovedException ignore) {
        evicted.add(entry.txKey());

        if (log.isDebugEnabled())
          log.debug("Got removed entry when adding to remote transaction (will ignore): " + cached);

        return false;
      }
    }
  }
コード例 #2
0
ファイル: GridNearTxLocal.java プロジェクト: WinnieRzz/ignite
  /** {@inheritDoc} */
  @Override
  public void close() throws IgniteCheckedException {
    super.close();

    if (accessMap != null) {
      assert optimistic();

      for (Map.Entry<IgniteTxKey, IgniteCacheExpiryPolicy> e : accessMap.entrySet()) {
        if (e.getValue().entries() != null) {
          GridCacheContext cctx0 = cctx.cacheContext(e.getKey().cacheId());

          if (cctx0.isNear()) cctx0.near().dht().sendTtlUpdateRequest(e.getValue());
          else cctx0.dht().sendTtlUpdateRequest(e.getValue());
        }
      }

      accessMap = null;
    }
  }
コード例 #3
0
ファイル: GridNearTxLocal.java プロジェクト: WinnieRzz/ignite
  /**
   * @param entries Entries.
   * @param dhtVer DHT version.
   * @param pendingVers Pending versions.
   * @param committedVers Committed versions.
   * @param rolledbackVers Rolled back versions.
   */
  void readyNearLocks(
      Collection<IgniteTxEntry> entries,
      GridCacheVersion dhtVer,
      Collection<GridCacheVersion> pendingVers,
      Collection<GridCacheVersion> committedVers,
      Collection<GridCacheVersion> rolledbackVers) {
    for (IgniteTxEntry txEntry : entries) {
      while (true) {
        GridCacheContext cacheCtx = txEntry.cached().context();

        assert cacheCtx.isNear();

        GridDistributedCacheEntry entry = (GridDistributedCacheEntry) txEntry.cached();

        try {
          // Handle explicit locks.
          GridCacheVersion explicit = txEntry.explicitVersion();

          if (explicit == null) {
            entry.readyNearLock(xidVer, dhtVer, committedVers, rolledbackVers, pendingVers);
          }

          break;
        } catch (GridCacheEntryRemovedException ignored) {
          assert entry.obsoleteVersion() != null;

          if (log.isDebugEnabled())
            log.debug(
                "Replacing obsolete entry in remote transaction [entry="
                    + entry
                    + ", tx="
                    + this
                    + ']');

          // Replace the entry.
          txEntry.cached(txEntry.context().cache().entryEx(txEntry.key()));
        }
      }
    }
  }
コード例 #4
0
  /**
   * Starts activity.
   *
   * @throws IgniteInterruptedCheckedException If interrupted.
   */
  public void init() throws IgniteInterruptedCheckedException {
    if (isDone()) return;

    if (init.compareAndSet(false, true)) {
      if (isDone()) return;

      try {
        // Wait for event to occur to make sure that discovery
        // will return corresponding nodes.
        U.await(evtLatch);

        assert discoEvt != null : this;
        assert !dummy && !forcePreload : this;

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

        oldestNode.set(oldest);

        startCaches();

        // True if client node joined or failed.
        boolean clientNodeEvt;

        if (F.isEmpty(reqs)) {
          int type = discoEvt.type();

          assert type == EVT_NODE_JOINED || type == EVT_NODE_LEFT || type == EVT_NODE_FAILED
              : discoEvt;

          clientNodeEvt = CU.clientNode(discoEvt.eventNode());
        } else {
          assert discoEvt.type() == EVT_DISCOVERY_CUSTOM_EVT : discoEvt;

          boolean clientOnlyStart = true;

          for (DynamicCacheChangeRequest req : reqs) {
            if (!req.clientStartOnly()) {
              clientOnlyStart = false;

              break;
            }
          }

          clientNodeEvt = clientOnlyStart;
        }

        if (clientNodeEvt) {
          ClusterNode node = discoEvt.eventNode();

          // Client need to initialize affinity for local join event or for stated client caches.
          if (!node.isLocal()) {
            for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
              if (cacheCtx.isLocal()) continue;

              GridDhtPartitionTopology top = cacheCtx.topology();

              top.updateTopologyVersion(exchId, this, -1, stopping(cacheCtx.cacheId()));

              if (cacheCtx.affinity().affinityTopologyVersion() == AffinityTopologyVersion.NONE) {
                initTopology(cacheCtx);

                top.beforeExchange(this);
              } else
                cacheCtx.affinity().clientEventTopologyChange(discoEvt, exchId.topologyVersion());
            }

            if (exchId.isLeft())
              cctx.mvcc().removeExplicitNodeLocks(exchId.nodeId(), exchId.topologyVersion());

            onDone(exchId.topologyVersion());

            skipPreload = cctx.kernalContext().clientNode();

            return;
          }
        }

        if (cctx.kernalContext().clientNode()) {
          skipPreload = true;

          for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
            if (cacheCtx.isLocal()) continue;

            GridDhtPartitionTopology top = cacheCtx.topology();

            top.updateTopologyVersion(exchId, this, -1, stopping(cacheCtx.cacheId()));
          }

          for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
            if (cacheCtx.isLocal()) continue;

            initTopology(cacheCtx);
          }

          if (oldestNode.get() != null) {
            rmtNodes =
                new ConcurrentLinkedQueue<>(
                    CU.aliveRemoteServerNodesWithCaches(cctx, exchId.topologyVersion()));

            rmtIds = Collections.unmodifiableSet(new HashSet<>(F.nodeIds(rmtNodes)));

            ready.set(true);

            initFut.onDone(true);

            if (log.isDebugEnabled()) log.debug("Initialized future: " + this);

            sendPartitions();
          } else onDone(exchId.topologyVersion());

          return;
        }

        assert oldestNode.get() != null;

        for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
          if (isCacheAdded(cacheCtx.cacheId(), exchId.topologyVersion())) {
            if (cacheCtx
                .discovery()
                .cacheAffinityNodes(cacheCtx.name(), topologyVersion())
                .isEmpty())
              U.quietAndWarn(log, "No server nodes found for cache client: " + cacheCtx.namex());
          }

          cacheCtx.preloader().onExchangeFutureAdded();
        }

        List<String> cachesWithoutNodes = null;

        if (exchId.isLeft()) {
          for (String name : cctx.cache().cacheNames()) {
            if (cctx.discovery().cacheAffinityNodes(name, topologyVersion()).isEmpty()) {
              if (cachesWithoutNodes == null) cachesWithoutNodes = new ArrayList<>();

              cachesWithoutNodes.add(name);

              // Fire event even if there is no client cache started.
              if (cctx.gridEvents().isRecordable(EventType.EVT_CACHE_NODES_LEFT)) {
                Event evt =
                    new CacheEvent(
                        name,
                        cctx.localNode(),
                        cctx.localNode(),
                        "All server nodes have left the cluster.",
                        EventType.EVT_CACHE_NODES_LEFT,
                        0,
                        false,
                        null,
                        null,
                        null,
                        null,
                        false,
                        null,
                        false,
                        null,
                        null,
                        null);

                cctx.gridEvents().record(evt);
              }
            }
          }
        }

        if (cachesWithoutNodes != null) {
          StringBuilder sb =
              new StringBuilder(
                  "All server nodes for the following caches have left the cluster: ");

          for (int i = 0; i < cachesWithoutNodes.size(); i++) {
            String cache = cachesWithoutNodes.get(i);

            sb.append('\'').append(cache).append('\'');

            if (i != cachesWithoutNodes.size() - 1) sb.append(", ");
          }

          U.quietAndWarn(log, sb.toString());

          U.quietAndWarn(log, "Must have server nodes for caches to operate.");
        }

        assert discoEvt != null;

        assert exchId.nodeId().equals(discoEvt.eventNode().id());

        for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
          GridClientPartitionTopology clientTop =
              cctx.exchange().clearClientTopology(cacheCtx.cacheId());

          long updSeq = clientTop == null ? -1 : clientTop.lastUpdateSequence();

          // Update before waiting for locks.
          if (!cacheCtx.isLocal())
            cacheCtx
                .topology()
                .updateTopologyVersion(exchId, this, updSeq, stopping(cacheCtx.cacheId()));
        }

        // Grab all alive remote nodes with order of equal or less than last joined node.
        rmtNodes =
            new ConcurrentLinkedQueue<>(
                CU.aliveRemoteServerNodesWithCaches(cctx, exchId.topologyVersion()));

        rmtIds = Collections.unmodifiableSet(new HashSet<>(F.nodeIds(rmtNodes)));

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

        for (Map.Entry<UUID, GridDhtPartitionsFullMessage> m : fullMsgs.entrySet())
          // If received any messages, process them.
          onReceive(m.getKey(), m.getValue());

        AffinityTopologyVersion topVer = exchId.topologyVersion();

        for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
          if (cacheCtx.isLocal()) continue;

          // Must initialize topology after we get discovery event.
          initTopology(cacheCtx);

          cacheCtx.preloader().updateLastExchangeFuture(this);
        }

        IgniteInternalFuture<?> partReleaseFut = cctx.partitionReleaseFuture(topVer);

        // Assign to class variable so it will be included into toString() method.
        this.partReleaseFut = partReleaseFut;

        if (log.isDebugEnabled()) log.debug("Before waiting for partition release future: " + this);

        while (true) {
          try {
            partReleaseFut.get(2 * cctx.gridConfig().getNetworkTimeout(), TimeUnit.MILLISECONDS);

            break;
          } catch (IgniteFutureTimeoutCheckedException ignored) {
            // Print pending transactions and locks that might have led to hang.
            dumpPendingObjects();
          }
        }

        if (log.isDebugEnabled()) log.debug("After waiting for partition release future: " + this);

        if (!F.isEmpty(reqs)) blockGateways();

        if (exchId.isLeft())
          cctx.mvcc().removeExplicitNodeLocks(exchId.nodeId(), exchId.topologyVersion());

        IgniteInternalFuture<?> locksFut = cctx.mvcc().finishLocks(exchId.topologyVersion());

        while (true) {
          try {
            locksFut.get(2 * cctx.gridConfig().getNetworkTimeout(), TimeUnit.MILLISECONDS);

            break;
          } catch (IgniteFutureTimeoutCheckedException ignored) {
            U.warn(
                log,
                "Failed to wait for locks release future. "
                    + "Dumping pending objects that might be the cause: "
                    + cctx.localNodeId());

            U.warn(log, "Locked entries:");

            Map<IgniteTxKey, Collection<GridCacheMvccCandidate>> locks =
                cctx.mvcc().unfinishedLocks(exchId.topologyVersion());

            for (Map.Entry<IgniteTxKey, Collection<GridCacheMvccCandidate>> e : locks.entrySet())
              U.warn(log, "Locked entry [key=" + e.getKey() + ", mvcc=" + e.getValue() + ']');
          }
        }

        for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
          if (cacheCtx.isLocal()) continue;

          // Notify replication manager.
          GridCacheContext drCacheCtx =
              cacheCtx.isNear() ? cacheCtx.near().dht().context() : cacheCtx;

          if (drCacheCtx.isDrEnabled()) drCacheCtx.dr().beforeExchange(topVer, exchId.isLeft());

          // Partition release future is done so we can flush the write-behind store.
          cacheCtx.store().forceFlush();

          // Process queued undeploys prior to sending/spreading map.
          cacheCtx.preloader().unwindUndeploys();

          GridDhtPartitionTopology top = cacheCtx.topology();

          assert topVer.equals(top.topologyVersion())
              : "Topology version is updated only in this class instances inside single ExchangeWorker thread.";

          top.beforeExchange(this);
        }

        for (GridClientPartitionTopology top : cctx.exchange().clientTopologies()) {
          top.updateTopologyVersion(exchId, this, -1, stopping(top.cacheId()));

          top.beforeExchange(this);
        }
      } catch (IgniteInterruptedCheckedException e) {
        onDone(e);

        throw e;
      } catch (Throwable e) {
        U.error(
            log,
            "Failed to reinitialize local partitions (preloading will be stopped): " + exchId,
            e);

        onDone(e);

        if (e instanceof Error) throw (Error) e;

        return;
      }

      if (F.isEmpty(rmtIds)) {
        onDone(exchId.topologyVersion());

        return;
      }

      ready.set(true);

      initFut.onDone(true);

      if (log.isDebugEnabled()) log.debug("Initialized future: " + this);

      // If this node is not oldest.
      if (!oldestNode.get().id().equals(cctx.localNodeId())) sendPartitions();
      else {
        boolean allReceived = allReceived();

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

      scheduleRecheck();
    } else assert false : "Skipped init future: " + this;
  }
コード例 #5
0
ファイル: GridNearTxLocal.java プロジェクト: WinnieRzz/ignite
  /** {@inheritDoc} */
  @Override
  public IgniteInternalFuture<Void> loadMissing(
      final GridCacheContext cacheCtx,
      boolean readThrough,
      boolean async,
      final Collection<KeyCacheObject> keys,
      final boolean skipVals,
      final boolean needVer,
      boolean keepBinary,
      final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c) {
    if (cacheCtx.isNear()) {
      return cacheCtx
          .nearTx()
          .txLoadAsync(
              this,
              keys,
              readThrough,
              /*deserializeBinary*/ false,
              accessPolicy(cacheCtx, keys),
              skipVals,
              needVer)
          .chain(
              new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
                @Override
                public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
                  try {
                    Map<Object, Object> map = f.get();

                    processLoaded(map, keys, needVer, c);

                    return null;
                  } catch (Exception e) {
                    setRollbackOnly();

                    throw new GridClosureException(e);
                  }
                }
              });
    } else if (cacheCtx.isColocated()) {
      if (keys.size() == 1) {
        final KeyCacheObject key = F.first(keys);

        return cacheCtx
            .colocated()
            .loadAsync(
                key,
                readThrough,
                /*force primary*/ needVer,
                topologyVersion(),
                CU.subjectId(this, cctx),
                resolveTaskName(),
                /*deserializeBinary*/ false,
                accessPolicy(cacheCtx, keys),
                skipVals,
                /*can remap*/ true,
                needVer,
                /*keepCacheObject*/ true)
            .chain(
                new C1<IgniteInternalFuture<Object>, Void>() {
                  @Override
                  public Void apply(IgniteInternalFuture<Object> f) {
                    try {
                      Object val = f.get();

                      processLoaded(key, val, needVer, skipVals, c);

                      return null;
                    } catch (Exception e) {
                      setRollbackOnly();

                      throw new GridClosureException(e);
                    }
                  }
                });
      } else {
        return cacheCtx
            .colocated()
            .loadAsync(
                keys,
                readThrough,
                /*force primary*/ needVer,
                topologyVersion(),
                CU.subjectId(this, cctx),
                resolveTaskName(),
                /*deserializeBinary*/ false,
                accessPolicy(cacheCtx, keys),
                skipVals,
                /*can remap*/ true,
                needVer,
                /*keepCacheObject*/ true)
            .chain(
                new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
                  @Override
                  public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
                    try {
                      Map<Object, Object> map = f.get();

                      processLoaded(map, keys, needVer, c);

                      return null;
                    } catch (Exception e) {
                      setRollbackOnly();

                      throw new GridClosureException(e);
                    }
                  }
                });
      }
    } else {
      assert cacheCtx.isLocal();

      return super.loadMissing(
          cacheCtx, readThrough, async, keys, skipVals, keepBinary, needVer, c);
    }
  }