/** @param e Error. */ void onError(Throwable e) { tx.commitError(e); if (err.compareAndSet(null, e)) { boolean marked = tx.setRollbackOnly(); if (e instanceof GridCacheTxRollbackException) { if (marked) { try { tx.rollback(); } catch (GridException ex) { U.error(log, "Failed to automatically rollback transaction: " + tx, ex); } } } else if (tx.implicit() && tx.isSystemInvalidate()) { // Finish implicit transaction on heuristic error. try { tx.close(); } catch (GridException ex) { U.error(log, "Failed to invalidate transaction: " + tx, ex); } } onComplete(); } }
/** * Message received callback. * * @param src Sender node ID. * @param msg Received message. * @return {@code True}. */ public boolean onMessageReceived(UUID src, GridHadoopMessage msg) { if (msg instanceof GridHadoopShuffleMessage) { GridHadoopShuffleMessage m = (GridHadoopShuffleMessage) msg; try { job(m.jobId()).onShuffleMessage(m); } catch (GridException e) { U.error(log, "Message handling failed.", e); } try { // Reply with ack. send0(src, new GridHadoopShuffleAck(m.id(), m.jobId())); } catch (GridException e) { U.error( log, "Failed to reply back to shuffle message sender [snd=" + src + ", msg=" + msg + ']', e); } } else if (msg instanceof GridHadoopShuffleAck) { GridHadoopShuffleAck m = (GridHadoopShuffleAck) msg; try { job(m.jobId()).onShuffleAck(m); } catch (GridException e) { U.error(log, "Message handling failed.", e); } } else throw new IllegalStateException( "Unknown message type received to Hadoop shuffle [src=" + src + ", msg=" + msg + ']'); return true; }
/** * Creates new HTTP requests handler. * * @param hnd Handler. * @param authChecker Authentication checking closure. * @param log Logger. */ GridJettyRestHandler( GridRestProtocolHandler hnd, GridClosure<String, Boolean> authChecker, GridLogger log) { assert hnd != null; assert log != null; this.hnd = hnd; this.log = log; this.authChecker = authChecker; // Init default page and favicon. try { initDefaultPage(); if (log.isDebugEnabled()) log.debug("Initialized default page."); } catch (IOException e) { U.warn(log, "Failed to initialize default page: " + e.getMessage()); } try { initFavicon(); if (log.isDebugEnabled()) log.debug( favicon != null ? "Initialized favicon, size: " + favicon.length : "Favicon is null."); } catch (IOException e) { U.warn(log, "Failed to initialize favicon: " + e.getMessage()); } }
/** {@inheritDoc} */ @Nullable @Override public Map<? extends GridComputeJob, GridNode> map( List<GridNode> subgrid, @Nullable GridBiTuple<Set<UUID>, A> arg) throws GridException { assert arg != null; assert arg.get1() != null; start = U.currentTimeMillis(); boolean debug = debugState(g); if (debug) logStart(g.log(), getClass(), start); Set<UUID> nodeIds = arg.get1(); Map<GridComputeJob, GridNode> map = U.newHashMap(nodeIds.size()); try { taskArg = arg.get2(); for (GridNode node : subgrid) if (nodeIds.contains(node.id())) map.put(job(taskArg), node); return map; } finally { if (debug) logMapped(g.log(), getClass(), map.values()); } }
/** * Processes unlock request. * * @param nodeId Sender node ID. * @param req Unlock request. */ @SuppressWarnings({"unchecked"}) private void processUnlockRequest(UUID nodeId, GridDistributedUnlockRequest req) { assert nodeId != null; try { ClassLoader ldr = ctx.deploy().globalLoader(); List<byte[]> keys = req.keyBytes(); for (byte[] keyBytes : keys) { K key = (K) U.unmarshal(ctx.marshaller(), new ByteArrayInputStream(keyBytes), ldr); while (true) { boolean created = false; GridDistributedCacheEntry<K, V> entry = peekexx(key); if (entry == null) { entry = entryexx(key); created = true; } try { entry.doneRemote( req.version(), req.version(), req.committedVersions(), req.rolledbackVersions()); // Note that we don't reorder completed versions here, // as there is no point to reorder relative to the version // we are about to remove. if (entry.removeLock(req.version())) { if (log.isDebugEnabled()) log.debug("Removed lock [lockId=" + req.version() + ", key=" + key + ']'); if (created && entry.markObsolete(req.version())) removeIfObsolete(entry.key()); } else if (log.isDebugEnabled()) log.debug( "Received unlock request for unknown candidate " + "(added to cancelled locks set): " + req); break; } catch (GridCacheEntryRemovedException ignored) { if (log.isDebugEnabled()) log.debug( "Received remove lock request for removed entry (will retry) [entry=" + entry + ", req=" + req + ']'); } } } } catch (GridException e) { U.error(log, "Failed to unmarshal unlock key (unlock will not be performed): " + req, e); } }
/** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { depEnabled = in.readBoolean(); if (depEnabled) { topicBytes = U.readByteArray(in); predBytes = U.readByteArray(in); clsName = U.readString(in); depInfo = (GridDeploymentInfoBean) in.readObject(); } else { topic = in.readObject(); pred = (GridBiPredicate<UUID, Object>) in.readObject(); } }
/** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeBoolean(depEnabled); if (depEnabled) { U.writeByteArray(out, topicBytes); U.writeByteArray(out, predBytes); U.writeString(out, clsName); out.writeObject(depInfo); } else { out.writeObject(topic); out.writeObject(pred); } }
/** {@inheritDoc} */ @Override public void loadCache(GridBiInClosure<K, V> c, @Nullable Object... args) throws GridException { ExecutorService exec = new ThreadPoolExecutor( threadsCnt, threadsCnt, 0L, MILLISECONDS, new ArrayBlockingQueue<Runnable>(batchQueueSize), new BlockingRejectedExecutionHandler()); Iterator<I> iter = inputIterator(args); Collection<I> buf = new ArrayList<>(batchSize); try { while (iter.hasNext()) { if (Thread.currentThread().isInterrupted()) { U.warn(log, "Working thread was interrupted while loading data."); break; } buf.add(iter.next()); if (buf.size() == batchSize) { exec.submit(new Worker(c, buf, args)); buf = new ArrayList<>(batchSize); } } if (!buf.isEmpty()) exec.submit(new Worker(c, buf, args)); } catch (RejectedExecutionException ignored) { // Because of custom RejectedExecutionHandler. assert false : "RejectedExecutionException was thrown while it shouldn't."; } finally { exec.shutdown(); try { exec.awaitTermination(Long.MAX_VALUE, MILLISECONDS); } catch (InterruptedException ignored) { U.warn(log, "Working thread was interrupted while waiting for put operations to complete."); Thread.currentThread().interrupt(); } } }
/** Initializes future. */ @SuppressWarnings({"unchecked"}) void finish() { if (mappings != null) { finish(mappings.values()); markInitialized(); if (!isSync()) { boolean complete = true; for (GridFuture<?> f : pending()) // Mini-future in non-sync mode gets done when message gets sent. if (isMini(f) && !f.isDone()) complete = false; if (complete) onComplete(); } } else { assert !commit; try { tx.rollback(); } catch (GridException e) { U.error(log, "Failed to rollback empty transaction: " + tx, e); } markInitialized(); } }
/** * Method cleans up all events that either outnumber queue size or exceeds time-to-live value. It * does none if someone else cleans up queue (lock is locked) or if there are queue readers * (readersNum > 0). */ private void cleanupQueue() { long now = U.currentTimeMillis(); long queueOversize = evts.sizex() - expireCnt; for (int i = 0; i < queueOversize && evts.sizex() > expireCnt; i++) { GridEvent expired = evts.poll(); if (log.isDebugEnabled()) log.debug("Event expired by count: " + expired); } while (true) { ConcurrentLinkedDeque8.Node<GridEvent> node = evts.peekx(); if (node == null) // Queue is empty. break; GridEvent evt = node.item(); if (evt == null) // Competing with another thread. continue; if (now - evt.timestamp() < expireAgeMs) break; if (evts.unlinkx(node) && log.isDebugEnabled()) log.debug("Event expired by age: " + node.item()); } }
/** Checks reversing. */ private void checkReversing() { if (!keepGoing) U.warn( log, "Suspect logic - reversing listener return status (was 'true', then 'false', " + "now 'true' again)."); }
/** @return Nodes to execute on. */ private Collection<GridNode> nodes() { GridCacheMode cacheMode = cctx.config().getCacheMode(); switch (cacheMode) { case LOCAL: if (prj != null) U.warn( log, "Ignoring query projection because it's executed over LOCAL cache " + "(only local node will be queried): " + this); return Collections.singletonList(cctx.localNode()); case REPLICATED: if (prj != null) return nodes(cctx, prj); GridCacheDistributionMode mode = cctx.config().getDistributionMode(); return mode == PARTITIONED_ONLY || mode == NEAR_PARTITIONED ? Collections.singletonList(cctx.localNode()) : Collections.singletonList(F.rand(nodes(cctx, null))); case PARTITIONED: return nodes(cctx, prj); default: throw new IllegalStateException("Unknown cache distribution mode: " + cacheMode); } }
/** {@inheritDoc} */ @Override public boolean onDone(GridCacheTx tx, Throwable err) { if ((initialized() || err != null) && super.onDone(tx, err)) { if (error() instanceof GridCacheTxHeuristicException) { long topVer = this.tx.topologyVersion(); for (GridCacheTxEntry<K, V> e : this.tx.writeMap().values()) { try { if (e.op() != NOOP && !cctx.affinity().localNode(e.key(), topVer)) { GridCacheEntryEx<K, V> cacheEntry = cctx.cache().peekEx(e.key()); if (cacheEntry != null) cacheEntry.invalidate(null, this.tx.xidVersion()); } } catch (Throwable t) { U.error(log, "Failed to invalidate entry.", t); if (t instanceof Error) throw (Error) t; } } } // Don't forget to clean up. cctx.mvcc().removeFuture(this); return true; } return false; }
/** {@inheritDoc} */ @SuppressWarnings({"unchecked"}) @Override public void listenAsync(@Nullable final GridInClosure<? super GridFuture<R>> lsnr) { if (lsnr != null) { checkValid(); boolean done; synchronized (mux) { done = this.done; if (!done) lsnrs.add(lsnr); } if (done) { try { if (syncNotify) notifyListener(lsnr); else ctx.closure() .runLocalSafe( new GPR() { @Override public void run() { notifyListener(lsnr); } }, true); } catch (IllegalStateException ignore) { U.warn( null, "Future notification will not proceed because grid is stopped: " + ctx.gridName()); } } } }
/** @throws IOException If failed. */ private void initFavicon() throws IOException { assert favicon == null; InputStream in = getClass().getResourceAsStream("favicon.ico"); if (in != null) { BufferedInputStream bis = new BufferedInputStream(in); ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { byte[] buf = new byte[2048]; while (true) { int n = bis.read(buf); if (n == -1) break; bos.write(buf, 0, n); } favicon = bos.toByteArray(); } finally { U.closeQuiet(bis); } } }
/** * @param nodeId Sender node ID. * @param msg Response to prepare request. */ private void processPrepareResponse(UUID nodeId, GridDistributedTxPrepareResponse<K, V> msg) { assert nodeId != null; assert msg != null; GridReplicatedTxLocal<K, V> tx = ctx.tm().tx(msg.version()); if (tx == null) { if (log.isDebugEnabled()) log.debug( "Received prepare response for non-existing transaction [senderNodeId=" + nodeId + ", res=" + msg + ']'); return; } GridReplicatedTxPrepareFuture<K, V> future = (GridReplicatedTxPrepareFuture<K, V>) tx.future(); if (future != null) future.onResult(nodeId, msg); else U.error( log, "Received prepare response for transaction with no future [res=" + msg + ", tx=" + tx + ']'); }
/** * @param nodeId Sender node ID. * @param msg Finish transaction response. */ private void processFinishResponse(UUID nodeId, GridDistributedTxFinishResponse<K, V> msg) { GridReplicatedTxCommitFuture<K, V> fut = (GridReplicatedTxCommitFuture<K, V>) ctx.mvcc().<GridCacheTx>future(msg.xid().id(), msg.futureId()); if (fut != null) fut.onResult(nodeId); else U.warn(log, "Received finish response for unknown transaction: " + msg); }
/** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { super.writeExternal(out); out.writeLong(topVer); out.writeBoolean(implicitTx); out.writeBoolean(implicitSingleTx); out.writeBoolean(syncCommit); out.writeBoolean(syncRollback); out.writeObject(filterBytes); U.writeArray(out, dhtVers); assert miniId != null; U.writeGridUuid(out, miniId); }
/** * @param bytes Bytes to unmarshal. * @param ldr Class loader. * @param <T> Type to unmarshal. * @return Unmarshalled value. * @throws GridException If unmarshal failed. */ @SuppressWarnings({"unchecked", "TypeMayBeWeakened"}) private <T> T unmarshal(GridSwapByteArray bytes, ClassLoader ldr) throws GridException { return (T) U.unmarshal( cctx.marshaller(), new ByteArrayInputStream(bytes.getArray(), bytes.getOffset(), bytes.getLength()), ldr); }
/** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { super.readExternal(in); topVer = in.readLong(); implicitTx = in.readBoolean(); implicitSingleTx = in.readBoolean(); syncCommit = in.readBoolean(); syncRollback = in.readBoolean(); filterBytes = (byte[][]) in.readObject(); dhtVers = U.readArray(in, CU.versionArrayFactory()); miniId = U.readGridUuid(in); assert miniId != null; }
/** * Reconstructs object on demarshalling. * * @return Reconstructed object. * @throws ObjectStreamException Thrown in case of demarshalling error. */ private Object readResolve() throws ObjectStreamException { GridTuple2<GridCacheContext, String> t = stash.get(); try { return t.get1().dataStructures().sequence(t.get2(), 0L, false, false); } catch (GridException e) { throw U.withCause(new InvalidObjectException(e.getMessage()), e); } }
/** * @param nodeId Sender. * @param res Result. */ void onResult(UUID nodeId, GridNearLockResponse<K, V> res) { if (!isDone()) { if (log.isDebugEnabled()) log.debug( "Received lock response from node [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']'); for (GridFuture<Boolean> fut : pending()) { if (isMini(fut)) { MiniFuture mini = (MiniFuture) fut; if (mini.futureId().equals(res.miniId())) { assert mini.node().id().equals(nodeId); if (log.isDebugEnabled()) log.debug("Found mini future for response [mini=" + mini + ", res=" + res + ']'); mini.onResult(res); if (log.isDebugEnabled()) log.debug( "Future after processed lock response [fut=" + this + ", mini=" + mini + ", res=" + res + ']'); return; } } } U.warn( log, "Failed to find mini future for response (perhaps due to stale message) [res=" + res + ", fut=" + this + ']'); } else if (log.isDebugEnabled()) log.debug( "Ignoring lock response from node (future is done) [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']'); }
/** * Removes locks regardless of whether they are owned or not for given version and keys. * * @param ver Lock version. * @param keys Keys. */ @SuppressWarnings({"unchecked"}) public void removeLocks(GridCacheVersion ver, Collection<? extends K> keys) { if (keys.isEmpty()) return; Collection<GridRichNode> nodes = ctx.remoteNodes(keys); try { // Send request to remove from remote nodes. GridDistributedUnlockRequest<K, V> req = new GridDistributedUnlockRequest<K, V>(keys.size()); req.version(ver); for (K key : keys) { while (true) { GridDistributedCacheEntry<K, V> entry = peekexx(key); try { if (entry != null) { GridCacheMvccCandidate<K> cand = entry.candidate(ver); if (cand != null) { // Remove candidate from local node first. if (entry.removeLock(cand.version())) { // If there is only local node in this lock's topology, // then there is no reason to distribute the request. if (nodes.isEmpty()) continue; req.addKey(entry.key(), entry.getOrMarshalKeyBytes(), ctx); } } } break; } catch (GridCacheEntryRemovedException ignored) { if (log.isDebugEnabled()) log.debug( "Attempted to remove lock from removed entry (will retry) [rmvVer=" + ver + ", entry=" + entry + ']'); } } } if (nodes.isEmpty()) return; req.completedVersions(ctx.tm().committedVersions(ver), ctx.tm().rolledbackVersions(ver)); if (!req.keyBytes().isEmpty()) // We don't wait for reply to this message. ctx.io().safeSend(nodes, req, null); } catch (GridException ex) { U.error(log, "Failed to unlock the lock for keys: " + keys, ex); } }
/** * Reconstructs object on demarshalling. * * @return Reconstructed object. * @throws ObjectStreamException Thrown in case of demarshalling error. */ @SuppressWarnings({"ConstantConditions"}) private Object readResolve() throws ObjectStreamException { GridTuple2<GridCacheContext, String> t = stash.get(); try { return t.get1().dataStructures().countDownLatch(t.get2(), 0, false, false); } catch (GridException e) { throw U.withCause(new InvalidObjectException(e.getMessage()), e); } }
/** {@inheritDoc} */ @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { try { if (executor.isShutdown()) throw new RejectedExecutionException(); else executor.getQueue().put(r); } catch (InterruptedException ignored) { U.warn(log, "Working thread was interrupted while loading data."); Thread.currentThread().interrupt(); } }
/** @param jobId Job id. */ public void jobFinished(GridHadoopJobId jobId) { GridHadoopShuffleJob job = jobs.remove(jobId); if (job != null) { try { job.close(); } catch (GridException e) { U.error(log, "Failed to close job: " + jobId, e); } } }
/** * Stops shuffle. * * @param cancel If should cancel all ongoing activities. */ @Override public void stop(boolean cancel) { for (GridHadoopShuffleJob job : jobs.values()) { try { job.close(); } catch (GridException e) { U.error(log, "Failed to close job.", e); } } jobs.clear(); }
/** * Reconstructs object on demarshalling. * * @return Reconstructed object. * @throws ObjectStreamException Thrown in case of demarshalling error. */ @SuppressWarnings("unchecked") private Object readResolve() throws ObjectStreamException { try { GridBiTuple<GridCacheContext, String> t = stash.get(); return t.get1().dataStructures().atomicReference(t.get2(), null, false); } catch (GridException e) { throw U.withCause(new InvalidObjectException(e.getMessage()), e); } finally { stash.remove(); } }
/** * Flushes every internal buffer if buffer was flushed before passed in threshold. * * <p>Does not wait for result and does not fail on errors assuming that this method should be * called periodically. */ @Override public void tryFlush() throws GridInterruptedException { if (!busyLock.enterBusy()) return; try { for (Buffer buf : bufMappings.values()) buf.flush(); lastFlushTime = U.currentTimeMillis(); } finally { leaveBusy(); } }
/** * Adds new participant to deployment. * * @param dep Shared deployment. * @param meta Request metadata. * @return {@code True} if participant was added. */ private boolean addParticipant(SharedDeployment dep, GridDeploymentMetadata meta) { assert dep != null; assert meta != null; assert Thread.holdsLock(mux); if (!checkModeMatch(dep, meta)) return false; if (meta.participants() != null) { for (Map.Entry<UUID, GridTuple2<GridUuid, Long>> e : meta.participants().entrySet()) { dep.addParticipant(e.getKey(), e.getValue().get1(), e.getValue().get2()); if (log.isDebugEnabled()) log.debug( "Added new participant [nodeId=" + e.getKey() + ", clsLdrId=" + e.getValue().get1() + ", seqNum=" + e.getValue().get2() + ']'); } } if (dep.deployMode() == CONTINUOUS || meta.participants() == null) { if (!dep.addParticipant(meta.senderNodeId(), meta.classLoaderId(), meta.sequenceNumber())) { U.warn( log, "Failed to create shared mode deployment " + "(requested class loader was already undeployed, did sender node leave grid?) " + "[clsLdrId=" + meta.classLoaderId() + ", senderNodeId=" + meta.senderNodeId() + ']'); return false; } if (log.isDebugEnabled()) log.debug( "Added new participant [nodeId=" + meta.senderNodeId() + ", clsLdrId=" + meta.classLoaderId() + ", seqNum=" + meta.sequenceNumber() + ']'); } return true; }