/** {@inheritDoc} */ @Override public Serializable reduce(List<GridComputeJobResult> results) throws GridException { if (log.isInfoEnabled()) log.info("Reducing job [job=" + this + ", results=" + results + ']'); if (results.size() > 1) fail(); return results.get(0).getData(); }
/** {@inheritDoc} */ @Override public Map<? extends GridComputeJob, GridNode> map(List<GridNode> subgrid, Integer arg) throws GridException { assert taskSes != null; assert arg != null; assert arg > 0; Map<GridSessionLoadTestJob, GridNode> map = new HashMap<>(subgrid.size()); Iterator<GridNode> iter = subgrid.iterator(); Random rnd = new Random(); params = new HashMap<>(arg); Collection<UUID> assigned = new ArrayList<>(subgrid.size()); for (int i = 0; i < arg; i++) { // Recycle iterator. if (!iter.hasNext()) iter = subgrid.iterator(); String paramName = UUID.randomUUID().toString(); int paramVal = rnd.nextInt(); taskSes.setAttribute(paramName, paramVal); GridNode node = iter.next(); assigned.add(node.id()); map.put(new GridSessionLoadTestJob(paramName), node); params.put(paramName, paramVal); if (log.isDebugEnabled()) log.debug("Set session attribute [name=" + paramName + ", value=" + paramVal + ']'); } taskSes.setAttribute("nodes", assigned); return map; }
/** {@inheritDoc} */ @SuppressWarnings("BusyWait") @Override public Boolean reduce(List<GridComputeJobResult> results) throws GridException { assert taskSes != null; assert results != null; assert params != null; assert !params.isEmpty(); assert results.size() == params.size(); Map<String, Integer> receivedParams = new HashMap<>(); boolean allAttrReceived = false; int cnt = 0; while (!allAttrReceived && cnt++ < 3) { allAttrReceived = true; for (Map.Entry<String, Integer> entry : params.entrySet()) { assert taskSes.getAttribute(entry.getKey()) != null; Integer newVal = (Integer) taskSes.getAttribute(entry.getKey()); assert newVal != null; receivedParams.put(entry.getKey(), newVal); if (newVal != entry.getValue() + 1) allAttrReceived = false; } if (!allAttrReceived) { try { Thread.sleep(100); } catch (InterruptedException e) { throw new GridException("Thread interrupted.", e); } } } if (log.isDebugEnabled()) { for (Map.Entry<String, Integer> entry : receivedParams.entrySet()) { log.debug( "Received session attr value [name=" + entry.getKey() + ", val=" + entry.getValue() + ", expected=" + (params.get(entry.getKey()) + 1) + ']'); } } return allAttrReceived; }
/** {@inheritDoc} */ @Override public String reduce(List<GridComputeJobResult> results) throws GridException { assert results.size() == 1; return results.get(0).getData(); }
/** * This method is called to map or split grid task into multiple grid jobs. This is the first * method that gets called when task execution starts. * * @param data Task execution argument. Can be {@code null}. This is the same argument as the one * passed into {@code Grid#execute(...)} methods. * @param subgrid Nodes available for this task execution. Note that order of nodes is guaranteed * to be randomized by container. This ensures that every time you simply iterate through grid * nodes, the order of nodes will be random which over time should result into all nodes being * used equally. * @return Map of grid jobs assigned to subgrid node. Unless {@link * GridComputeTaskContinuousMapper} is injected into task, if {@code null} or empty map is * returned, exception will be thrown. * @throws GridException If mapping could not complete successfully. This exception will be thrown * out of {@link GridComputeTaskFuture#get()} method. */ @Override public Map<? extends GridComputeJob, GridNode> map( List<GridNode> subgrid, @Nullable final Collection<Integer> data) throws GridException { assert !subgrid.isEmpty(); // Give preference to wanted node. Otherwise, take the first one. GridNode targetNode = F.find( subgrid, subgrid.get(0), new GridPredicate<GridNode>() { @Override public boolean apply(GridNode e) { return preferredNode.equals(e.id()); } }); return Collections.singletonMap( new GridComputeJobAdapter() { @GridLoggerResource private GridLogger log; @GridInstanceResource private Grid grid; @Override public Object execute() throws GridException { log.info("Going to put data: " + data.size()); GridCache<Object, Object> cache = grid.cache(cacheName); assert cache != null; Map<Integer, T2<Integer, Collection<Integer>>> putMap = groupData(data); for (Map.Entry<Integer, T2<Integer, Collection<Integer>>> entry : putMap.entrySet()) { T2<Integer, Collection<Integer>> pair = entry.getValue(); Object affKey = pair.get1(); // Group lock partition. try (GridCacheTx tx = cache.txStartPartition( cache.affinity().partition(affKey), optimistic ? OPTIMISTIC : PESSIMISTIC, REPEATABLE_READ, 0, pair.get2().size())) { for (Integer val : pair.get2()) cache.put(val, val); tx.commit(); } } log.info("Finished put data: " + data.size()); return data; } /** * Groups values by partitions. * * @param data Data to put. * @return Grouped map. */ private Map<Integer, T2<Integer, Collection<Integer>>> groupData(Iterable<Integer> data) { GridCache<Object, Object> cache = grid.cache(cacheName); Map<Integer, T2<Integer, Collection<Integer>>> res = new HashMap<>(); for (Integer val : data) { int part = cache.affinity().partition(val); T2<Integer, Collection<Integer>> tup = res.get(part); if (tup == null) { tup = new T2<Integer, Collection<Integer>>(val, new LinkedList<Integer>()); res.put(part, tup); } tup.get2().add(val); } return res; } }, targetNode); }