org.jppf.server.node.local.AsyncLocalNodeIO Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jppf-server Show documentation
Show all versions of jppf-server Show documentation
JPPF, the open source grid computing solution
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.server.node.local;
import static org.jppf.node.protocol.BundleParameter.*;
import java.util.*;
import java.util.concurrent.*;
import org.jppf.JPPFUnsupportedOperationException;
import org.jppf.io.*;
import org.jppf.node.protocol.*;
import org.jppf.node.protocol.graph.TaskGraphInfo;
import org.jppf.server.nio.nodeserver.LocalNodeMessage;
import org.jppf.server.nio.nodeserver.async.*;
import org.jppf.server.node.*;
import org.jppf.utils.LoggingUtils;
import org.slf4j.*;
/**
* This class performs the I/O operations requested by the JPPFNode, for reading the task bundles and sending the results back.
* @author Laurent Cohen
*/
public class AsyncLocalNodeIO extends AbstractNodeIO {
/**
* Logger for this class.
*/
private static Logger log = LoggerFactory.getLogger(AsyncLocalNodeIO.class);
/**
* Determines whether the debug level is enabled in the logging configuration, without the cost of a method call.
*/
private static boolean debugEnabled = LoggingUtils.isDebugEnabled(log);
/**
* The I/O channel for this node.
*/
private AsyncNodeContext channel;
/**
* Initialize this TaskIO with the specified node.
* @param node - the node who owns this TaskIO.
*/
public AsyncLocalNodeIO(final JPPFLocalNode node) {
super(node);
this.channel = (AsyncNodeContext) node.getNodeConnection().getChannel();
}
@Override
protected Object[] deserializeObjects() throws Exception {
Object[] result = null;
LocalNodeMessage currentMessage = null;
synchronized(channel.getLocalNodeReadLock()) {
if (debugEnabled) log.debug("waiting for next request");
// wait until a message has been sent by the server
currentMessage = (LocalNodeMessage) channel.takeNextMessageToSend();
if (debugEnabled) log.debug("got request");
}
final DataLocation location = currentMessage.getLocations().get(0);
final TaskBundle bundle = (TaskBundle) IOHelper.unwrappedData(location, node.getHelper().getSerializer());
node.getExecutionManager().addPendingJobEntry(bundle);
if (debugEnabled) log.debug("got bundle " + bundle);
result = deserializeObjects(bundle, currentMessage);
if (debugEnabled) log.debug("got all data");
return result;
}
/**
* Performs the actions required if reloading the classes is necessary.
* @throws Exception if any error occurs.
*/
@Override
protected void handleReload() throws Exception {
node.setClassLoader(null);
node.initHelper();
}
@Override
protected Object[] deserializeObjects(final TaskBundle bundle) throws Exception {
throw new JPPFUnsupportedOperationException("method " + getClass().getName() + ".deserializeObjects(TaskBundle) should never be called for a local node");
}
/**
* Perform the deserialization of the objects received through the socket connection.
* @param bundle the message header that contains information about the tasks and data provider.
* @param currentMessage contains the tasks and data provider inserialized form.
* @return an array of objects deserialized from the socket stream.
* @throws Exception if an error occurs while deserializing.
*/
protected Object[] deserializeObjects(final TaskBundle bundle, final LocalNodeMessage currentMessage) throws Exception {
final TaskGraphInfo graphInfo = bundle.getParameter(BundleParameter.JOB_TASK_GRAPH_INFO, null);
final int dependencyCount = (graphInfo == null) ? 0 : graphInfo.getNbDependencies();
final int count = bundle.getTaskCount() + dependencyCount;
final Object[] list = new Object[count + 2];
list[0] = bundle;
try {
initializeBundleData(bundle);
if (debugEnabled) log.debug("bundle task count = {}, dependencies = {}, handshake = {}", bundle.getTaskCount(), dependencyCount, bundle.isHandshake());
if (!bundle.isHandshake()) {
TaskThreadLocals.setRequestUuid(bundle.getUuid());
final boolean clientAccess = !bundle.getParameter(FROM_PERSISTENCE, false);
final JPPFLocalContainer cont = (JPPFLocalContainer) node.getClassLoaderManager().getContainer(bundle.getUuidPath().getList(), clientAccess, (Object[]) null);
if (!node.isOffline() && !bundle.getSLA().isRemoteClassLoadingEnabled()) cont.getClassLoader().setRemoteClassLoadingDisabled(true);
node.getLifeCycleEventHandler().fireJobHeaderLoaded(bundle, cont.getClassLoader());
cont.deserializeObjects(list, 1 + count, currentMessage, node.getSerializationExecutor());
} else {
// skip null data provider
}
if (debugEnabled) log.debug("got all data");
} catch(final Throwable t) {
log.error("Exception occurred while deserializing the tasks", t);
bundle.setTaskCount(0);
bundle.setParameter(NODE_EXCEPTION_PARAM, t);
}
return list;
}
@Override
protected void sendResults(final TaskBundle bundle, final List> tasks) throws Exception {
if (debugEnabled) log.debug("writing {} results for {}", tasks.size(), bundle);
final ExecutorService executor = node.getSerializationExecutor();
finalizeBundleData(bundle, tasks);
final List> futureList = new ArrayList<>((tasks == null) ? 1 : tasks.size() + 1);
final JPPFContainer cont = node.getContainer(bundle.isNotification() ? node.getHandshakeUuidPath() : bundle.getUuidPath().getList());
int submitCount = 0;
futureList.add(executor.submit(new ObjectSerializationTask(bundle, cont, bundle, submitCount++)));
if (!bundle.isNotification()) {
for (final Task task : tasks) futureList.add(executor.submit(new ObjectSerializationTask(task, cont, bundle, submitCount++)));
}
final LocalNodeMessage message = (LocalNodeMessage) channel.newMessage();
for (final Future f: futureList) {
final DataLocation location = f.get();
message.addLocation(location);
}
message.setBundle(bundle);
synchronized(channel.getLocalNodeWriteLock()) {
if (debugEnabled) log.debug("wrote full results");
final AsyncNodeMessageHandler handler = channel.getServer().getMessageHandler();
if (bundle.isHandshake()) handler.handshakeReceived(channel, message);
else handler.resultsReceived(channel, message);
}
}
}