コード例 #1
0
  /**
   * @param fut Future to remove.
   * @return {@code True} if removed.
   */
  @SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter"})
  public boolean removeFuture(GridCacheFuture<?> fut) {
    if (!fut.trackable()) return true;

    Collection<GridCacheFuture<?>> cur = futs.get(fut.version());

    if (cur == null) return false;

    boolean rmv, empty;

    synchronized (cur) {
      rmv = cur.remove(fut);

      empty = cur.isEmpty();
    }

    if (rmv) {
      if (log.isDebugEnabled()) log.debug("Removed future from future map: " + fut);
    } else if (log.isDebugEnabled())
      log.debug(
          "Attempted to remove a non-registered future (has it been already removed?): " + fut);

    if (empty && futs.remove(fut.version(), cur))
      if (log.isDebugEnabled())
        log.debug("Removed future list from futures map for lock version: " + fut.version());

    return rmv;
  }
コード例 #2
0
        /** {@inheritDoc} */
        @SuppressWarnings({"unchecked"})
        @Override
        public void onOwnerChanged(
            GridCacheEntryEx entry, GridCacheMvccCandidate prev, GridCacheMvccCandidate owner) {
          assert entry != null;
          assert owner != prev : "New and previous owner are identical instances: " + owner;
          assert owner == null || prev == null || !owner.version().equals(prev.version())
              : "New and previous owners have identical versions [owner="
                  + owner
                  + ", prev="
                  + prev
                  + ']';

          if (log.isDebugEnabled())
            log.debug(
                "Received owner changed callback ["
                    + entry.key()
                    + ", owner="
                    + owner
                    + ", prev="
                    + prev
                    + ']');

          if (owner != null && (owner.local() || owner.nearLocal())) {
            Collection<? extends GridCacheFuture> futCol = futs.get(owner.version());

            if (futCol != null) {
              for (GridCacheFuture fut : futCol) {
                if (fut instanceof GridCacheMvccFuture && !fut.isDone()) {
                  GridCacheMvccFuture<Boolean> mvccFut = (GridCacheMvccFuture<Boolean>) fut;

                  // Since this method is called outside of entry synchronization,
                  // we can safely invoke any method on the future.
                  // Also note that we don't remove future here if it is done.
                  // The removal is initiated from within future itself.
                  if (mvccFut.onOwnerChanged(entry, owner)) return;
                }
              }
            }
          }

          if (log.isDebugEnabled())
            log.debug(
                "Lock future not found for owner change callback (will try transaction futures) [owner="
                    + owner
                    + ", prev="
                    + prev
                    + ", entry="
                    + entry
                    + ']');

          // If no future was found, delegate to transaction manager.
          if (cctx.tm().onOwnerChanged(entry, owner)) {
            if (log.isDebugEnabled()) log.debug("Found transaction for changed owner: " + owner);
          } else if (log.isDebugEnabled())
            log.debug("Failed to find transaction for changed owner: " + owner);

          for (FinishLockFuture f : finishFuts) f.recheck(entry);
        }
コード例 #3
0
  /**
   * Gets future for given future ID and lock ID.
   *
   * @param ver Lock ID.
   * @param futId Future ID.
   * @return Future.
   */
  @SuppressWarnings({"unchecked"})
  @Nullable
  public GridCacheFuture future(GridCacheVersion ver, IgniteUuid futId) {
    Collection<? extends GridCacheFuture> futs = this.futs.get(ver);

    if (futs != null)
      for (GridCacheFuture<?> fut : futs)
        if (fut.futureId().equals(futId)) {
          if (log.isDebugEnabled()) log.debug("Found future in futures map: " + fut);

          return fut;
        }

    if (log.isDebugEnabled())
      log.debug("Failed to find future in futures map [ver=" + ver + ", futId=" + futId + ']');

    return null;
  }
コード例 #4
0
        @Override
        public void onEvent(Event evt) {
          assert evt instanceof DiscoveryEvent;
          assert evt.type() == EVT_NODE_FAILED || evt.type() == EVT_NODE_LEFT;

          DiscoveryEvent discoEvt = (DiscoveryEvent) evt;

          if (log.isDebugEnabled())
            log.debug("Processing node left [nodeId=" + discoEvt.eventNode().id() + "]");

          for (Collection<GridCacheFuture<?>> futsCol : futs.values()) {
            for (GridCacheFuture<?> fut : futsCol) {
              if (!fut.trackable()) {
                if (log.isDebugEnabled()) log.debug("Skipping non-trackable future: " + fut);

                continue;
              }

              fut.onNodeLeft(discoEvt.eventNode().id());

              if (fut.isCancelled() || fut.isDone()) removeFuture(fut);
            }
          }

          for (IgniteInternalFuture<?> fut : atomicFuts.values()) {
            if (fut instanceof GridCacheFuture) {
              GridCacheFuture cacheFut = (GridCacheFuture) fut;

              cacheFut.onNodeLeft(discoEvt.eventNode().id());

              if (cacheFut.isCancelled() || cacheFut.isDone()) {
                GridCacheVersion futVer = cacheFut.version();

                if (futVer != null) atomicFuts.remove(futVer, fut);
              }
            }
          }
        }
コード例 #5
0
  /**
   * Adds future.
   *
   * @param fut Future.
   * @return {@code True} if added.
   */
  @SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter"})
  public boolean addFuture(final GridCacheFuture<?> fut) {
    if (fut.isDone()) {
      fut.markNotTrackable();

      return true;
    }

    if (!fut.trackable()) return true;

    while (true) {
      Collection<GridCacheFuture<?>> old =
          futs.putIfAbsent(
              fut.version(),
              new ConcurrentLinkedDeque8<GridCacheFuture<?>>() {
                /** */
                private int hash;

                {
                  // Make sure that we add future to queue before
                  // adding queue to the map of futures.
                  add(fut);
                }

                @Override
                public int hashCode() {
                  if (hash == 0) hash = System.identityHashCode(this);

                  return hash;
                }

                @Override
                public boolean equals(Object obj) {
                  return obj == this;
                }
              });

      if (old != null) {
        boolean empty, dup = false;

        synchronized (old) {
          empty = old.isEmpty();

          if (!empty) dup = old.contains(fut);

          if (!empty && !dup) old.add(fut);
        }

        // Future is being removed, so we force-remove here and try again.
        if (empty) {
          if (futs.remove(fut.version(), old)) {
            if (log.isDebugEnabled())
              log.debug("Removed future list from futures map for lock version: " + fut.version());
          }

          continue;
        }

        if (dup) {
          if (log.isDebugEnabled())
            log.debug("Found duplicate future in futures map (will not add): " + fut);

          return false;
        }
      }

      // Handle version mappings.
      if (fut instanceof GridCacheMappedVersion) {
        GridCacheVersion from = ((GridCacheMappedVersion) fut).mappedVersion();

        if (from != null) mapVersion(from, fut.version());
      }

      if (log.isDebugEnabled()) log.debug("Added future to future map: " + fut);

      break;
    }

    // Close window in case of node is gone before the future got added to
    // the map of futures.
    for (ClusterNode n : fut.nodes()) {
      if (cctx.discovery().node(n.id()) == null) fut.onNodeLeft(n.id());
    }

    // Just in case if future was completed before it was added.
    if (fut.isDone()) removeFuture(fut);
    else onFutureAdded(fut);

    return true;
  }