/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.ignite.internal.visor.query;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.compute.ComputeJob;
import org.apache.ignite.internal.processors.task.GridInternal;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.visor.VisorJob;
import org.apache.ignite.internal.visor.VisorMultiNodeTask;
import org.apache.ignite.internal.visor.VisorTaskArgument;
import org.apache.ignite.internal.visor.util.VisorClusterGroupEmptyException;
import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.internal.visor.util.VisorTaskUtils.logMapped;
/**
* Task for cleanup not needed SCAN or SQL queries result futures from node local.
*/
@GridInternal
public class VisorQueryCleanupTask extends VisorMultiNodeTask<VisorQueryCleanupTaskArg, Void, Void> {
/** */
private static final long serialVersionUID = 0L;
/** {@inheritDoc} */
@Override protected VisorJob<VisorQueryCleanupTaskArg, Void> job(VisorQueryCleanupTaskArg arg) {
return null;
}
/** {@inheritDoc} */
@Override protected Map<? extends ComputeJob, ClusterNode> map0(List<ClusterNode> subgrid,
@Nullable VisorTaskArgument<VisorQueryCleanupTaskArg> arg) {
Set<UUID> nodeIds = taskArg.getQueryIds().keySet();
if (nodeIds.isEmpty())
throw new VisorClusterGroupEmptyException("Nothing to clear. List with node IDs is empty!");
Map<ComputeJob, ClusterNode> map = U.newHashMap(nodeIds.size());
try {
for (ClusterNode node : subgrid)
if (nodeIds.contains(node.id()))
map.put(new VisorQueryCleanupJob(taskArg.getQueryIds().get(node.id()), debug), node);
if (map.isEmpty()) {
StringBuilder notFoundNodes = new StringBuilder();
for (UUID nid : nodeIds)
notFoundNodes.append((notFoundNodes.length() == 0) ? "" : ",").append(U.id8(nid));
throw new VisorClusterGroupEmptyException("Failed to clear query results. Nodes are not available: [" +
notFoundNodes + "]");
}
return map;
}
finally {
if (debug)
logMapped(ignite.log(), getClass(), map.values());
}
}
/** {@inheritDoc} */
@Nullable @Override protected Void reduce0(List list) {
return null;
}
/**
* Job for cleanup not needed SCAN or SQL queries result futures from node local.
*/
private static class VisorQueryCleanupJob extends VisorJob<Collection<String>, Void> {
/** */
private static final long serialVersionUID = 0L;
/**
* Create job with specified argument.
*
* @param arg Job argument.
* @param debug Debug flag.
*/
protected VisorQueryCleanupJob(Collection<String> arg, boolean debug) {
super(arg, debug);
}
/** {@inheritDoc} */
@Override protected Void run(Collection<String> qryIds) {
ConcurrentMap<String, VisorQueryCursor> storage = ignite.cluster().nodeLocalMap();
for (String qryId : qryIds) {
VisorQueryCursor cur = storage.remove(qryId);
if (cur != null)
cur.close();
}
return null;
}
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(VisorQueryCleanupJob.class, this);
}
}
}