/** * @param sesId Session ID. * @param taskNodeId Task node ID. * @param taskName Task name. * @param dep Deployment. * @param taskClsName Task class name. * @param top Topology. * @param startTime Execution start time. * @param endTime Execution end time. * @param siblings Collection of siblings. * @param attrs Map of attributes. * @param fullSup {@code True} to enable distributed session attributes and checkpoints. * @return New session if one did not exist, or existing one. */ public GridTaskSessionImpl createTaskSession( GridUuid sesId, UUID taskNodeId, String taskName, @Nullable GridDeployment dep, String taskClsName, @Nullable Collection<UUID> top, long startTime, long endTime, Collection<GridComputeJobSibling> siblings, Map<Object, Object> attrs, boolean fullSup) { if (!fullSup) { return new GridTaskSessionImpl( taskNodeId, taskName, dep, taskClsName, sesId, top, startTime, endTime, siblings, attrs, ctx, fullSup); } while (true) { GridTaskSessionImpl ses = sesMap.get(sesId); if (ses == null) { GridTaskSessionImpl old = sesMap.putIfAbsent( sesId, ses = new GridTaskSessionImpl( taskNodeId, taskName, dep, taskClsName, sesId, top, startTime, endTime, siblings, attrs, ctx, fullSup)); if (old != null) ses = old; else // Return without acquire. return ses; } if (ses.acquire()) return ses; else sesMap.remove(sesId, ses); } }
/** * @param key Key to lock. * @return Sync object that should be passed to {@link #unlock(Object, Object)} method. */ public <T> Object lock(T key) { assert key != null; boolean interrupted = false; Sync t = new Sync(); try { while (true) { Sync old = locks.putIfAbsent(key, t); if (old != null) { while (true) { try { old.await(); break; } catch (InterruptedException ignored) { interrupted = true; } } } else return t; } } finally { if (interrupted) Thread.currentThread().interrupt(); } }
/** * @param p Partition number. * @param topVer Topology version. * @param create Create flag. * @param updateSeq Update sequence. * @return Local partition. */ private GridDhtLocalPartition localPartition( int p, AffinityTopologyVersion topVer, boolean create, boolean updateSeq) { while (true) { boolean belongs = cctx.affinity().localNode(p, topVer); GridDhtLocalPartition loc = locParts.get(p); if (loc != null && loc.state() == EVICTED) { locParts.remove(p, loc); if (!create) return null; if (!belongs) throw new GridDhtInvalidPartitionException( p, "Adding entry to evicted partition [part=" + p + ", topVer=" + topVer + ", this.topVer=" + this.topVer + ']'); continue; } if (loc == null && create) { if (!belongs) throw new GridDhtInvalidPartitionException( p, "Creating partition which does not belong [part=" + p + ", topVer=" + topVer + ", this.topVer=" + this.topVer + ']'); lock.writeLock().lock(); try { GridDhtLocalPartition old = locParts.putIfAbsent(p, loc = new GridDhtLocalPartition(cctx, p)); if (old != null) loc = old; else { if (updateSeq) this.updateSeq.incrementAndGet(); if (log.isDebugEnabled()) log.debug("Created local partition: " + loc); } } finally { lock.writeLock().unlock(); } } return loc; } }
/** * @param key Key to lock. * @return Sync object that should be passed to {@link #unlock(Object, Object)} method or {@code * null} if try lock failed. */ @Nullable public <T> Object tryLock(T key) { assert key != null; Sync t = new Sync(); Sync old = locks.putIfAbsent(key, t); return old != null ? null : t; }
/** * @param key Key to lock. * @return Sync object that should be passed to {@link #unlock(Object, Object)} method. * @throws InterruptedException If interrupted while acquiring lock. */ public <T> Object lockInterruptibly(T key) throws InterruptedException { assert key != null; Sync t = new Sync(); while (true) { Sync old = locks.putIfAbsent(key, t); if (old != null) old.await(); else return t; } }
/** * @param entries Entries. * @param resFut Result future. * @param activeKeys Active keys. * @param remaps Remaps count. */ private void load0( Collection<? extends Map.Entry<K, V>> entries, final GridFutureAdapter<Object> resFut, final Collection<K> activeKeys, final int remaps) { assert entries != null; if (remaps >= MAX_REMAP_CNT) { resFut.onDone(new GridException("Failed to finish operation (too many remaps): " + remaps)); return; } Map<GridNode, Collection<Map.Entry<K, V>>> mappings = new HashMap<>(); boolean initPda = ctx.deploy().enabled() && jobPda == null; for (Map.Entry<K, V> entry : entries) { GridNode node; try { K key = entry.getKey(); assert key != null; if (initPda) { jobPda = new DataLoaderPda(key, entry.getValue(), updater); initPda = false; } node = ctx.affinity().mapKeyToNode(cacheName, key); } catch (GridException e) { resFut.onDone(e); return; } if (node == null) { resFut.onDone( new GridTopologyException( "Failed to map key to node " + "(no nodes with cache found in topology) [infos=" + entries.size() + ", cacheName=" + cacheName + ']')); return; } Collection<Map.Entry<K, V>> col = mappings.get(node); if (col == null) mappings.put(node, col = new ArrayList<>()); col.add(entry); } for (final Map.Entry<GridNode, Collection<Map.Entry<K, V>>> e : mappings.entrySet()) { final UUID nodeId = e.getKey().id(); Buffer buf = bufMappings.get(nodeId); if (buf == null) { Buffer old = bufMappings.putIfAbsent(nodeId, buf = new Buffer(e.getKey())); if (old != null) buf = old; } final Collection<Map.Entry<K, V>> entriesForNode = e.getValue(); GridInClosure<GridFuture<?>> lsnr = new GridInClosure<GridFuture<?>>() { @Override public void apply(GridFuture<?> t) { try { t.get(); for (Map.Entry<K, V> e : entriesForNode) activeKeys.remove(e.getKey()); if (activeKeys.isEmpty()) resFut.onDone(); } catch (GridException e1) { if (log.isDebugEnabled()) log.debug("Future finished with error [nodeId=" + nodeId + ", err=" + e1 + ']'); if (cancelled) { resFut.onDone( new GridException( "Data loader has been cancelled: " + GridDataLoaderImpl.this, e1)); } else load0(entriesForNode, resFut, activeKeys, remaps + 1); } } }; GridFutureAdapter<?> f; try { f = buf.update(entriesForNode, lsnr); } catch (GridInterruptedException e1) { resFut.onDone(e1); return; } if (ctx.discovery().node(nodeId) == null) { if (bufMappings.remove(nodeId, buf)) buf.onNodeLeft(); if (f != null) f.onDone( new GridTopologyException( "Failed to wait for request completion " + "(node has left): " + nodeId)); } } }