/** {@inheritDoc} */
  @Override
  public void stop() {
    spi.setListener(null);

    Map<String, List<GridDeployment>> copy;

    synchronized (mux) {
      copy = new HashMap<String, List<GridDeployment>>(cache);

      for (Entry<String, List<GridDeployment>> entry : copy.entrySet()) {
        entry.setValue(new ArrayList<GridDeployment>(entry.getValue()));
      }
    }

    for (List<GridDeployment> deps : copy.values()) {
      for (GridDeployment cls : deps) {
        // We don't record event, as recording causes invocation of
        // discovery manager which is already stopped.
        undeploy(cls.classLoader(), /*don't record event. */ false);
      }
    }

    if (log.isDebugEnabled()) {
      log.debug(stopInfo());
    }
  }
  /**
   * Records undeploy event.
   *
   * @param dep Undeployed class loader.
   * @param recordEvt Flag indicating whether to record events.
   */
  private void recordUndeploy(GridDeployment dep, boolean recordEvt) {
    assert dep.isUndeployed();

    if (ctx.event().isRecordable(EVT_TASK_UNDEPLOYED)
        || ctx.event().isRecordable(EVT_CLASS_UNDEPLOYED)) {
      for (Class<?> cls : dep.deployedClasses()) {
        boolean isTask = isTask(cls);

        String msg =
            isTask ? "Task locally undeployed: " + cls : "Class locally undeployed: " + cls;

        if (ctx.event().isRecordable(isTask ? EVT_TASK_UNDEPLOYED : EVT_CLASS_UNDEPLOYED)) {
          if (recordEvt) {
            GridDeploymentEvent evt = new GridDeploymentEvent();

            evt.message(msg);
            evt.nodeId(ctx.localNodeId());
            evt.type(isTask ? EVT_TASK_UNDEPLOYED : EVT_CLASS_UNDEPLOYED);
            evt.alias(getAlias(dep, cls));

            ctx.event().record(evt);
          }
        }

        if (log.isInfoEnabled()) {
          log.info(msg);
        }
      }
    }
  }
  /**
   * @param alias Class alias.
   * @return Deployed class.
   */
  @Nullable
  private GridDeployment getDeployment(String alias) {
    assert Thread.holdsLock(mux);

    LinkedList<GridDeployment> deps = cache.get(alias);

    if (deps != null) {
      assert !deps.isEmpty();

      GridDeployment dep = deps.getFirst();

      if (!dep.isUndeployed()) {
        return dep;
      }
    }

    return null;
  }
  /** {@inheritDoc} */
  @Nullable
  @Override
  public GridDeployment getDeployment(GridUuid ldrId) {
    synchronized (mux) {
      for (List<GridDeployment> deps : cache.values()) {
        for (GridDeployment dep : deps) {
          if (dep.classLoaderId().equals(ldrId)) {
            return dep;
          }
        }
      }
    }

    for (GridDeployment dep : ctx.task().getUsedDeployments()) {
      if (dep.classLoaderId().equals(ldrId)) {
        return dep;
      }
    }

    return null;
  }
  /**
   * @param ldr Class loader to undeploy.
   * @param recEvt Whether or not to record the event.
   */
  private void undeploy(ClassLoader ldr, boolean recEvt) {
    Collection<GridDeployment> doomed = new HashSet<GridDeployment>();

    synchronized (mux) {
      for (Iterator<LinkedList<GridDeployment>> i1 = cache.values().iterator(); i1.hasNext(); ) {
        LinkedList<GridDeployment> deps = i1.next();

        for (Iterator<GridDeployment> i2 = deps.iterator(); i2.hasNext(); ) {
          GridDeployment dep = i2.next();

          if (dep.classLoader() == ldr) {
            dep.undeploy();

            i2.remove();

            doomed.add(dep);

            if (log.isInfoEnabled()) {
              log.info("Removed undeployed class: " + dep);
            }
          }
        }

        if (deps.isEmpty()) {
          i1.remove();
        }
      }
    }

    for (GridDeployment dep : doomed) {
      if (dep.isObsolete()) {
        // Resource cleanup.
        ctx.resource().onUndeployed(dep);
      }

      if (recEvt) {
        recordUndeploy(dep, true);
      }
    }
  }
  /**
   * Gets alias for a class.
   *
   * @param dep Deployment.
   * @param cls Class.
   * @return Alias for a class.
   */
  private String getAlias(GridDeployment dep, Class<?> cls) {
    String alias = cls.getName();

    if (isTask(cls)) {
      GridTaskName ann = dep.annotation(cls, GridTaskName.class);

      if (ann != null) {
        alias = ann.value();
      }
    }

    return alias;
  }
示例#7
0
 /** @return Task internal version. */
 public long getSequenceNumber() {
   return dep == null ? 0 : dep.sequenceNumber();
 }
示例#8
0
 /** @return Task version. */
 public String getUserVersion() {
   return dep == null ? "" : dep.userVersion();
 }
  /**
   * @param depMode Deployment mode.
   * @param ldr Class loader to deploy.
   * @param cls Class.
   * @param alias Class alias.
   * @return Deployment.
   */
  @SuppressWarnings({"ConstantConditions"})
  private GridDeployment deploy(
      GridDeploymentMode depMode, ClassLoader ldr, Class<?> cls, String alias) {
    assert Thread.holdsLock(mux);

    LinkedList<GridDeployment> cachedDeps = null;

    GridDeployment dep = null;

    // Find existing class loader info.
    for (LinkedList<GridDeployment> deps : cache.values()) {
      for (GridDeployment d : deps) {
        if (d.classLoader() == ldr) {
          // Cache class and alias.
          d.addDeployedClass(cls, alias);

          cachedDeps = deps;

          dep = d;

          break;
        }
      }

      if (cachedDeps != null) {
        break;
      }
    }

    if (cachedDeps != null) {
      assert dep != null;

      cache.put(alias, cachedDeps);

      if (!cls.getName().equals(alias)) {
        // Cache by class name as well.
        cache.put(cls.getName(), cachedDeps);
      }

      return dep;
    }

    GridUuid ldrId = GridUuid.randomUuid();

    long seqNum = seq.incrementAndGet();

    String userVer = getUserVersion(ldr);

    dep = new GridDeployment(depMode, ldr, ldrId, seqNum, userVer, cls.getName(), true);

    dep.addDeployedClass(cls, alias);

    LinkedList<GridDeployment> deps =
        F.addIfAbsent(cache, alias, F.<GridDeployment>newLinkedList());

    if (!deps.isEmpty()) {
      for (GridDeployment d : deps) {
        if (!d.isUndeployed()) {
          U.error(
              log,
              "Found more than one active deployment for the same resource "
                  + "[cls="
                  + cls
                  + ", depMode="
                  + depMode
                  + ", dep="
                  + d
                  + ']');

          return null;
        }
      }
    }

    // Add at the beginning of the list for future fast access.
    deps.addFirst(dep);

    if (!cls.getName().equals(alias)) {
      // Cache by class name as well.
      cache.put(cls.getName(), deps);
    }

    if (log.isDebugEnabled()) {
      log.debug("Created new deployment: " + dep);
    }

    return dep;
  }
  /** {@inheritDoc} */
  @Nullable
  @SuppressWarnings({"UnusedCatchParameter"})
  @Override
  public GridDeployment getDeployment(GridDeploymentMetadata meta) {
    GridDeployment dep;

    Class<?> cls = null;

    String alias = meta.alias();

    synchronized (mux) {
      // Validate metadata.
      assert meta.alias() != null;

      dep = getDeployment(meta.alias());

      if (dep != null) {
        if (log.isDebugEnabled()) {
          log.debug("Acquired deployment class from local cache: " + dep);
        }

        return dep;
      }

      GridDeploymentResource rsrc = spi.findResource(meta.alias());

      if (rsrc != null) {
        dep =
            deploy(
                ctx.config().getDeploymentMode(),
                rsrc.getClassLoader(),
                rsrc.getResourceClass(),
                alias);

        if (dep == null) {
          return null;
        }

        if (log.isDebugEnabled()) {
          log.debug("Acquired deployment class from SPI: " + dep);
        }
      }
      // Auto-deploy.
      else {
        ClassLoader ldr = meta.classLoader();

        if (ldr == null) {
          ldr = Thread.currentThread().getContextClassLoader();

          // Safety.
          if (ldr == null) {
            ldr = ctxLdr;
          }
        }

        // Don't auto-deploy locally in case of nested execution.
        if (ldr instanceof GridDeploymentClassLoader) {
          return null;
        }

        try {
          // Check that class can be loaded.
          cls = ldr.loadClass(meta.alias());

          spi.register(ldr, cls);

          rsrc = spi.findResource(alias);

          if (rsrc != null && rsrc.getResourceClass().equals(cls)) {
            if (log.isDebugEnabled()) {
              log.debug("Retrieved auto-loaded resource from spi: " + rsrc);
            }

            dep = deploy(ctx.config().getDeploymentMode(), ldr, cls, alias);

            if (dep == null) {
              return null;
            }
          } else {
            U.warn(
                log,
                "Failed to find resource from deployment SPI even after registering it: "
                    + meta.alias());

            return null;
          }
        } catch (ClassNotFoundException e) {
          if (log.isDebugEnabled()) {
            log.debug(
                "Failed to load class for local auto-deployment [ldr="
                    + ldr
                    + ", meta="
                    + meta
                    + ']');
          }

          return null;
        } catch (GridSpiException e) {
          U.error(log, "Failed to deploy local class: " + meta.alias(), e);

          return null;
        }
      }
    }

    if (cls != null) {
      recordDeploy(cls, alias, meta.isRecord());

      dep.addDeployedClass(cls, meta.className(), meta.alias());
    }

    if (log.isDebugEnabled()) {
      log.debug("Acquired deployment class: " + dep);
    }

    return dep;
  }