All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jppf.client.balancer.ChannelWrapperLocal Maven / Gradle / Ivy

The newest version!
/*
 * JPPF.
 * Copyright (C) 2005-2019 JPPF Team.
 * http://www.jppf.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jppf.client.balancer;

import java.util.*;
import java.util.concurrent.*;

import org.jppf.JPPFException;
import org.jppf.client.*;
import org.jppf.client.event.*;
import org.jppf.execute.*;
import org.jppf.load.balancer.BundlerHelper;
import org.jppf.load.balancer.persistence.*;
import org.jppf.management.*;
import org.jppf.node.protocol.*;
import org.jppf.utils.*;
import org.jppf.utils.configuration.JPPFProperties;
import org.slf4j.*;

/**
 * Context associated with a local channel serving state and tasks submission.
 * @author Martin JANDA
 */
public class ChannelWrapperLocal extends ChannelWrapper implements JPPFClientConnection {
  /**
   * Logger for this class.
   */
  private final static Logger log = LoggerFactory.getLogger(ChannelWrapperLocal.class);
  /**
   * Determines whether the debug level is enabled in the log configuration, without the cost of a method call.
   */
  private final static boolean debugEnabled = LoggingUtils.isDebugEnabled(log);
  /**
   * The task execution manager for this wrapper.
   */
  private final ExecutionManager executionManager;
  /**
   * Status of the connection.
   */
  private JPPFClientConnectionStatus status = JPPFClientConnectionStatus.ACTIVE;
  /**
   * Unique ID for the connection.
   */
  private final String connectionUuid = JPPFUuid.normalUUID();
  /**
   * List of status listeners for this connection.
   */
  private final List listeners = new CopyOnWriteArrayList<>();
  /**
   * Reference to the client 's executor.
   */
  private final JPPFClient client;
  /**
   * 
   */
  private boolean closed;
  /**
   * The name assigned to this connection.
   */
  private final String name;

  /**
   * Default initializer for local channel wrapper.
   * @param client reference to the JPPF client.
   */
  public ChannelWrapperLocal(final JPPFClient client) {
    this.client = client;
    this.name = client.getUuid() + "_local_executor";
    executionManager = new ClientExecutionManager(client.getConfig(), JPPFProperties.LOCAL_EXECUTION_THREADS);
    priority = client.getConfig().get(JPPFProperties.LOCAL_EXECUTION_PRIORITY);
    systemInfo = new JPPFSystemInformation(client.getConfig(), getConnectionUuid(), true, false);
    managementInfo = new JPPFManagementInfo("local", "local", -1, getConnectionUuid(), JPPFManagementInfo.NODE | JPPFManagementInfo.LOCAL, false);
    managementInfo.setSystemInfo(systemInfo);
    final String s = "client-local-executor";
    channelID = new Pair<>(s, CryptoUtils.computeHash(s, client.getBundlerFactory().getHashAlgorithm()));
  }

  @Override
  public String getUuid() {
    return connectionUuid;
  }

  @Override
  public String getConnectionUuid() {
    return connectionUuid;
  }

  @Override
  public JPPFClientConnectionStatus getStatus() {
    return status;
  }

  @Override
  public void setStatus(final JPPFClientConnectionStatus status) {
    synchronized(getMonitor()) {
      if (closed) return;
      this.oldStatus = this.status;
      final ExecutorStatus oldExecutionStatus = getExecutionStatus();
      final JPPFClientConnectionStatus oldValue = this.status;
      if (debugEnabled) log.debug("status changing from {} to {} for {}", oldValue, status, this);
      this.status = status;
      if (oldValue.isTerminatedStatus()) return;
      fireStatusChanged(oldValue, this.status);
      final ExecutorStatus newExecutionStatus = getExecutionStatus();
      fireExecutionStatusChanged(oldExecutionStatus, newExecutionStatus);
    }
  }

  @Override
  public void addClientConnectionStatusListener(final ClientConnectionStatusListener listener) {
    listeners.add(listener);
  }

  @Override
  public void removeClientConnectionStatusListener(final ClientConnectionStatusListener listener) {
    listeners.remove(listener);
  }

  /**
   * Notify all listeners that the status of this connection has changed.
   * @param oldStatus the connection status before the change.
   * @param newStatus the connection status after the change.
   */
  protected void fireStatusChanged(final JPPFClientConnectionStatus oldStatus, final JPPFClientConnectionStatus newStatus) {
    if (isClosed() || (oldStatus == newStatus)) return;
    final ClientConnectionStatusEvent event = new ClientConnectionStatusEvent(this, oldStatus);
    for (final ClientConnectionStatusListener listener : listeners) listener.statusChanged(event);
  }

  @Override
  public Future submit(final ClientTaskBundle bundle) {
    if (!isClosed()) {
      jobCount.set(1);
      if (debugEnabled) log.debug("locally submitting {}", bundle);
      setStatus(JPPFClientConnectionStatus.EXECUTING);
      final Runnable task = new LocalRunnable(bundle);
      bundle.jobDispatched(this);
      client.getExecutor().execute(task);
      if (debugEnabled) log.debug("end locally submitting {}", bundle);
    }
    return null;
  }

  @Override
  public boolean isLocal() {
    return true;
  }

  @Override
  public String toString() {
    return new StringBuilder(getClass().getSimpleName()).append('[')
    .append("status=").append(status)
    .append(", connectionUuid=").append(connectionUuid)
    .append(']').toString();
  }

  /**
   *
   */
  private class LocalRunnable implements Runnable {
    /**
     * The task bundle to execute.
     */
    private final ClientTaskBundle bundle;

    /**
     * Initialize this runnable for local execution.
     * @param bundle the execution to perform.
     */
    public LocalRunnable(final ClientTaskBundle bundle) {
      this.bundle = bundle;
    }

    @Override
    public void run() {
      Exception exception = null;
      final List> tasks = this.bundle.getTasksL();
      try {
        final long start = System.nanoTime();
        final DataProvider dataProvider = bundle.getJob().getDataProvider();
        for (final Task task : tasks) task.setDataProvider(dataProvider).setJob(bundle.getJob());
        executionManager.execute(bundle, tasks);
        bundle.resultsReceived(tasks);
        final double elapsed = System.nanoTime() - start;
        BundlerHelper.updateBundler(bundler, tasks.size(), elapsed);
        getLoadBalancerPersistenceManager().storeBundler(channelID, bundler, bundlerAlgorithm);
      } catch (final Throwable t) {
        log.error(t.getMessage(), t);
        exception = (t instanceof Exception) ? (Exception) t : new JPPFException(t);
        bundle.resultsReceived(t);
      } finally {
        bundle.taskCompleted(exception);
        bundle.getClientJob().removeChannel(ChannelWrapperLocal.this);
        setStatus(JPPFClientConnectionStatus.ACTIVE);
        jobCount.set(0);
      }
    }
  }

  @Override
  public void close() {
    synchronized(getMonitor()) {
      if (closed) return;
      closed = true;
      if (debugEnabled) log.debug("closing {}", this);
      super.close();
      try {
        if (!status.isTerminatedStatus()) setStatus(JPPFClientConnectionStatus.CLOSED);
        executionManager.shutdown();
      } finally {
        listenerList.clear();
        listeners.clear();
      }
    }
  }

  @Override
  public boolean cancel(final ClientTaskBundle bundle) {
    if (bundle.isCancelled()) return false;
    if (debugEnabled) log.debug("requesting cancel of jobId={}", bundle.getUuid());
    bundle.cancel();
    try {
      executionManager.cancelAllTasks(true, false);
    } catch (final Exception e) {
      log.error(e.getMessage(), e);
    }
    return true;
  }

  @Override
  LoadBalancerPersistenceManager getLoadBalancerPersistenceManager() {
    return (LoadBalancerPersistenceManager) client.getLoadBalancerPersistenceManagement();
  }

  /**
   * @return whether this channel is closed.
   */
  @Override
  public boolean isClosed() {
    synchronized(getMonitor()) {
      return closed;
    }
  }

  @Override
  public String getName() {
    return name;
  }

  @Override
  public boolean isSSLEnabled() {
    return false;
  }

  @Override
  public String getHost() {
    return "local";
  }

  @Override
  public int getPort() {
    return -1;
  }

  @Override
  public String getDriverUuid() {
    return null;
  }

  @Override
  public JPPFSystemInformation getSystemInfo() {
    return getSystemInformation();
  }

  @Override
  public JPPFConnectionPool getConnectionPool() {
    return null;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy