use of org.apache.ignite.internal.ComputeTaskInternalFuture in project ignite by apache.
the class GridTaskCommandHandler method handleAsyncUnsafe.
/**
* @param req Request.
* @return Future.
* @throws IgniteCheckedException On any handling exception.
*/
private IgniteInternalFuture<GridRestResponse> handleAsyncUnsafe(final GridRestRequest req) throws IgniteCheckedException {
assert req instanceof GridRestTaskRequest : "Invalid command for topology handler: " + req;
assert SUPPORTED_COMMANDS.contains(req.command());
if (log.isDebugEnabled())
log.debug("Handling task REST request: " + req);
GridRestTaskRequest req0 = (GridRestTaskRequest) req;
final GridFutureAdapter<GridRestResponse> fut = new GridFutureAdapter<>();
final GridRestResponse res = new GridRestResponse();
final GridClientTaskResultBean taskRestRes = new GridClientTaskResultBean();
// Set ID placeholder for the case it wouldn't be available due to remote execution.
taskRestRes.setId('~' + ctx.localNodeId().toString());
final boolean locExec = req0.destinationId() == null || req0.destinationId().equals(ctx.localNodeId()) || ctx.discovery().node(req0.destinationId()) == null;
switch(req.command()) {
case EXE:
{
final boolean async = req0.async();
final String name = req0.taskName();
if (F.isEmpty(name))
throw new IgniteCheckedException(missingParameter("name"));
final List<Object> params = req0.params();
long timeout = req0.timeout();
final UUID clientId = req.clientId();
final IgniteInternalFuture<Object> taskFut;
if (locExec) {
ctx.task().setThreadContextIfNotNull(TC_SUBJ_ID, clientId);
ctx.task().setThreadContext(TC_TIMEOUT, timeout);
Object arg = !F.isEmpty(params) ? params.size() == 1 ? params.get(0) : params.toArray() : null;
taskFut = ctx.task().execute(name, arg);
} else {
// Using predicate instead of node intentionally
// in order to provide user well-structured EmptyProjectionException.
ClusterGroup prj = ctx.grid().cluster().forPredicate(F.nodeForNodeId(req.destinationId()));
ctx.task().setThreadContext(TC_NO_FAILOVER, true);
taskFut = ctx.closure().callAsync(BALANCE, new ExeCallable(name, params, timeout, clientId), prj.nodes());
}
if (async) {
if (locExec) {
IgniteUuid tid = ((ComputeTaskInternalFuture) taskFut).getTaskSession().getId();
taskDescs.put(tid, new TaskDescriptor(false, null, null));
taskRestRes.setId(tid.toString() + '~' + ctx.localNodeId().toString());
res.setResponse(taskRestRes);
} else
res.setError("Asynchronous task execution is not supported for routing request.");
fut.onDone(res);
}
taskFut.listen(new IgniteInClosure<IgniteInternalFuture<Object>>() {
@Override
public void apply(IgniteInternalFuture<Object> taskFut) {
try {
TaskDescriptor desc;
try {
desc = new TaskDescriptor(true, taskFut.get(), null);
} catch (IgniteCheckedException e) {
if (e.hasCause(ClusterTopologyCheckedException.class, ClusterGroupEmptyCheckedException.class))
U.warn(log, "Failed to execute task due to topology issues (are all mapped " + "nodes alive?) [name=" + name + ", clientId=" + req.clientId() + ", err=" + e + ']');
else {
if (!X.hasCause(e, VisorClusterGroupEmptyException.class))
U.error(log, "Failed to execute task [name=" + name + ", clientId=" + req.clientId() + ']', e);
}
desc = new TaskDescriptor(true, null, e);
}
if (async && locExec) {
assert taskFut instanceof ComputeTaskInternalFuture;
IgniteUuid tid = ((ComputeTaskInternalFuture) taskFut).getTaskSession().getId();
taskDescs.put(tid, desc);
}
if (!async) {
if (desc.error() == null) {
try {
taskRestRes.setFinished(true);
taskRestRes.setResult(desc.result());
res.setResponse(taskRestRes);
fut.onDone(res);
} catch (IgniteException e) {
fut.onDone(new IgniteCheckedException("Failed to marshal task result: " + desc.result(), e));
}
} else
fut.onDone(desc.error());
}
} finally {
if (!async && !fut.isDone())
fut.onDone(new IgniteCheckedException("Failed to execute task (see server logs for details)."));
}
}
});
break;
}
case RESULT:
{
String id = req0.taskId();
if (F.isEmpty(id))
throw new IgniteCheckedException(missingParameter("id"));
StringTokenizer st = new StringTokenizer(id, "~");
if (st.countTokens() != 2)
throw new IgniteCheckedException("Failed to parse id parameter: " + id);
String tidParam = st.nextToken();
String resHolderIdParam = st.nextToken();
taskRestRes.setId(id);
try {
IgniteUuid tid = !F.isEmpty(tidParam) ? IgniteUuid.fromString(tidParam) : null;
UUID resHolderId = !F.isEmpty(resHolderIdParam) ? UUID.fromString(resHolderIdParam) : null;
if (tid == null || resHolderId == null)
throw new IgniteCheckedException("Failed to parse id parameter: " + id);
if (ctx.localNodeId().equals(resHolderId)) {
TaskDescriptor desc = taskDescs.get(tid);
if (desc == null)
throw new IgniteCheckedException("Task with provided id has never been started on provided node" + " [taskId=" + tidParam + ", taskResHolderId=" + resHolderIdParam + ']');
taskRestRes.setFinished(desc.finished());
if (desc.error() != null)
throw new IgniteCheckedException(desc.error().getMessage());
taskRestRes.setResult(desc.result());
res.setResponse(taskRestRes);
} else {
IgniteBiTuple<String, GridTaskResultResponse> t = requestTaskResult(resHolderId, tid);
if (t.get1() != null)
throw new IgniteCheckedException(t.get1());
GridTaskResultResponse taskRes = t.get2();
assert taskRes != null;
if (!taskRes.found())
throw new IgniteCheckedException("Task with provided id has never been started on provided node " + "[taskId=" + tidParam + ", taskResHolderId=" + resHolderIdParam + ']');
taskRestRes.setFinished(taskRes.finished());
if (taskRes.error() != null)
throw new IgniteCheckedException(taskRes.error());
taskRestRes.setResult(taskRes.result());
res.setResponse(taskRestRes);
}
} catch (IllegalArgumentException e) {
String msg = "Failed to parse parameters [taskId=" + tidParam + ", taskResHolderId=" + resHolderIdParam + ", err=" + e.getMessage() + ']';
if (log.isDebugEnabled())
log.debug(msg);
throw new IgniteCheckedException(msg, e);
}
fut.onDone(res);
break;
}
case NOOP:
{
fut.onDone(new GridRestResponse());
break;
}
default:
assert false : "Invalid command for task handler: " + req;
}
if (log.isDebugEnabled())
log.debug("Handled task REST request [res=" + res + ", req=" + req + ']');
return fut;
}
use of org.apache.ignite.internal.ComputeTaskInternalFuture in project ignite by apache.
the class GridCacheAdapter method globalLoadCacheAsync.
/**
* @param p Predicate.
* @param args Arguments.
* @throws IgniteCheckedException If failed.
* @return Load cache future.
*/
IgniteInternalFuture<?> globalLoadCacheAsync(@Nullable IgniteBiPredicate<K, V> p, @Nullable Object... args) throws IgniteCheckedException {
ctx.kernalContext().task().setThreadContext(TC_NO_FAILOVER, true);
CacheOperationContext opCtx = ctx.operationContextPerCall();
ExpiryPolicy plc = opCtx != null ? opCtx.expiry() : null;
Collection<ClusterNode> nodes = ctx.kernalContext().grid().cluster().forDataNodes(ctx.name()).nodes();
assert !F.isEmpty(nodes) : "There are not datanodes fo cache: " + ctx.name();
final boolean keepBinary = opCtx != null && opCtx.isKeepBinary();
ComputeTaskInternalFuture fut = ctx.kernalContext().closure().callAsync(BROADCAST, Collections.singletonList(new LoadCacheJobV2<>(ctx.name(), ctx.affinity().affinityTopologyVersion(), p, args, plc, keepBinary)), nodes);
return fut;
}
use of org.apache.ignite.internal.ComputeTaskInternalFuture in project ignite by apache.
the class GridTaskProcessor method startTask.
/**
* @param taskName Task name.
* @param taskCls Task class.
* @param task Task.
* @param sesId Task session ID.
* @param arg Optional task argument.
* @param sys If {@code true}, then system pool will be used.
* @param execName Name of the custom executor.
* @return Task future.
*/
@SuppressWarnings("unchecked")
private <T, R> ComputeTaskInternalFuture<R> startTask(@Nullable String taskName, @Nullable Class<?> taskCls, @Nullable ComputeTask<T, R> task, IgniteUuid sesId, @Nullable T arg, boolean sys, @Nullable String execName) {
assert sesId != null;
String taskClsName;
if (task != null)
taskClsName = task.getClass().getName();
else
taskClsName = taskCls != null ? taskCls.getName() : taskName;
// Get values from thread-local context.
Map<GridTaskThreadContextKey, Object> map = thCtx.get();
if (map == null)
map = EMPTY_ENUM_MAP;
else
// Reset thread-local context.
thCtx.set(null);
if (map.get(TC_SKIP_AUTH) == null)
ctx.security().authorize(taskClsName, SecurityPermission.TASK_EXECUTE, null);
Long timeout = (Long) map.get(TC_TIMEOUT);
long timeout0 = timeout == null || timeout == 0 ? Long.MAX_VALUE : timeout;
long startTime = U.currentTimeMillis();
long endTime = timeout0 + startTime;
// Account for overflow.
if (endTime < 0)
endTime = Long.MAX_VALUE;
IgniteCheckedException deployEx = null;
GridDeployment dep = null;
// User provided task name.
if (taskName != null) {
assert taskCls == null;
assert task == null;
try {
dep = ctx.deploy().getDeployment(taskName);
if (dep == null)
throw new IgniteDeploymentCheckedException("Unknown task name or failed to auto-deploy " + "task (was task (re|un)deployed?): " + taskName);
taskCls = dep.deployedClass(taskName);
if (taskCls == null)
throw new IgniteDeploymentCheckedException("Unknown task name or failed to auto-deploy " + "task (was task (re|un)deployed?) [taskName=" + taskName + ", dep=" + dep + ']');
if (!ComputeTask.class.isAssignableFrom(taskCls))
throw new IgniteCheckedException("Failed to auto-deploy task (deployed class is not a task) " + "[taskName=" + taskName + ", depCls=" + taskCls + ']');
} catch (IgniteCheckedException e) {
deployEx = e;
}
} else // Deploy user task class.
if (taskCls != null) {
assert task == null;
try {
// Implicit deploy.
dep = ctx.deploy().deploy(taskCls, U.detectClassLoader(taskCls));
if (dep == null)
throw new IgniteDeploymentCheckedException("Failed to auto-deploy task " + "(was task (re|un)deployed?): " + taskCls);
taskName = taskName(dep, taskCls, map);
} catch (IgniteCheckedException e) {
taskName = taskCls.getName();
deployEx = e;
}
} else // Deploy user task.
if (task != null) {
try {
ClassLoader ldr;
Class<?> cls;
if (task instanceof GridPeerDeployAware) {
GridPeerDeployAware depAware = (GridPeerDeployAware) task;
cls = depAware.deployClass();
ldr = depAware.classLoader();
// Set proper class name to make peer-loading possible.
taskCls = cls;
} else {
taskCls = task.getClass();
assert ComputeTask.class.isAssignableFrom(taskCls);
cls = task.getClass();
ldr = U.detectClassLoader(cls);
}
// Explicit deploy.
dep = ctx.deploy().deploy(cls, ldr);
if (dep == null)
throw new IgniteDeploymentCheckedException("Failed to auto-deploy task " + "(was task (re|un)deployed?): " + cls);
taskName = taskName(dep, taskCls, map);
} catch (IgniteCheckedException e) {
taskName = task.getClass().getName();
deployEx = e;
}
}
assert taskName != null;
if (log.isDebugEnabled())
log.debug("Task deployment: " + dep);
boolean fullSup = dep != null && taskCls != null && dep.annotation(taskCls, ComputeTaskSessionFullSupport.class) != null;
Collection<? extends ClusterNode> nodes = (Collection<? extends ClusterNode>) map.get(TC_SUBGRID);
Collection<UUID> top = nodes != null ? F.nodeIds(nodes) : null;
UUID subjId = getThreadContext(TC_SUBJ_ID);
if (subjId == null)
subjId = ctx.localNodeId();
boolean internal = false;
if (dep == null || taskCls == null)
assert deployEx != null;
else
internal = dep.internalTask(task, taskCls);
// Creates task session with task name and task version.
GridTaskSessionImpl ses = ctx.session().createTaskSession(sesId, ctx.localNodeId(), taskName, dep, taskCls == null ? null : taskCls.getName(), top, startTime, endTime, Collections.<ComputeJobSibling>emptyList(), Collections.emptyMap(), fullSup, internal, subjId, execName);
ComputeTaskInternalFuture<R> fut = new ComputeTaskInternalFuture<>(ses, ctx);
IgniteCheckedException securityEx = null;
if (ctx.security().enabled() && deployEx == null) {
try {
saveTaskMetadata(taskName);
} catch (IgniteCheckedException e) {
securityEx = e;
}
}
if (deployEx == null && securityEx == null) {
if (dep == null || !dep.acquire())
handleException(new IgniteDeploymentCheckedException("Task not deployed: " + ses.getTaskName()), fut);
else {
GridTaskWorker<?, ?> taskWorker = new GridTaskWorker<>(ctx, arg, ses, fut, taskCls, task, dep, new TaskEventListener(), map, subjId);
GridTaskWorker<?, ?> taskWorker0 = tasks.putIfAbsent(sesId, taskWorker);
assert taskWorker0 == null : "Session ID is not unique: " + sesId;
if (!ctx.clientDisconnected()) {
if (dep.annotation(taskCls, ComputeTaskMapAsync.class) != null) {
try {
// Start task execution in another thread.
if (sys)
ctx.getSystemExecutorService().execute(taskWorker);
else
ctx.getExecutorService().execute(taskWorker);
} catch (RejectedExecutionException e) {
tasks.remove(sesId);
release(dep);
handleException(new ComputeExecutionRejectedException("Failed to execute task " + "due to thread pool execution rejection: " + taskName, e), fut);
}
} else
taskWorker.run();
} else
taskWorker.finishTask(null, disconnectedError(null));
}
} else {
if (deployEx != null)
handleException(deployEx, fut);
else
handleException(securityEx, fut);
}
return fut;
}
Aggregations