/** {@inheritDoc} */ @Override public boolean waitForAttributes(Map<?, ?> attrs, long timeout) throws InterruptedException { A.notNull(attrs, "attrs"); if (attrs.isEmpty()) { return true; } if (timeout == 0) timeout = Long.MAX_VALUE; long now = System.currentTimeMillis(); // Prevent overflow. long end = now + timeout < 0 ? Long.MAX_VALUE : now + timeout; // Don't wait longer than session timeout. if (end > endTime) end = endTime; synchronized (mux) { boolean isFound = false; while (!closed && !(isFound = this.attrs.entrySet().containsAll(attrs.entrySet())) && now < end) { mux.wait(end - now); now = System.currentTimeMillis(); } if (closed) throw new InterruptedException("Session was closed: " + this); return isFound; } }
/** {@inheritDoc} */ @Override public Map<?, ?> waitForAttributes(Collection<?> keys, long timeout) throws InterruptedException { A.notNull(keys, "keys"); if (keys.isEmpty()) return Collections.emptyMap(); if (timeout == 0) timeout = Long.MAX_VALUE; long now = System.currentTimeMillis(); // Prevent overflow. long end = now + timeout < 0 ? Long.MAX_VALUE : now + timeout; // Don't wait longer than session timeout. if (end > endTime) end = endTime; synchronized (mux) { while (!closed && !attrs.keySet().containsAll(keys) && now < end) { mux.wait(end - now); now = System.currentTimeMillis(); } if (closed) throw new InterruptedException("Session was closed: " + this); Map<Object, Object> retVal = new HashMap<Object, Object>(keys.size()); for (Object key : keys) retVal.put(key, attrs.get(key)); return retVal; } }
/** {@inheritDoc} */ @Override public boolean waitForAttribute(Object key, Object val, long timeout) throws InterruptedException { A.notNull(key, "key"); if (timeout == 0) timeout = Long.MAX_VALUE; long now = System.currentTimeMillis(); // Prevent overflow. long end = now + timeout < 0 ? Long.MAX_VALUE : now + timeout; // Don't wait longer than session timeout. if (end > endTime) end = endTime; synchronized (mux) { boolean isFound = false; while (!closed && !(isFound = isAttributeSet(key, val)) && now < end) { mux.wait(end - now); now = System.currentTimeMillis(); } if (closed) throw new InterruptedException("Session was closed: " + this); return isFound; } }
/** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public <K, V> V waitForAttribute(K key, long timeout) throws InterruptedException { A.notNull(key, "key"); if (timeout == 0) timeout = Long.MAX_VALUE; long now = System.currentTimeMillis(); // Prevent overflow. long end = now + timeout < 0 ? Long.MAX_VALUE : now + timeout; // Don't wait longer than session timeout. if (end > endTime) end = endTime; synchronized (mux) { while (!closed && !attrs.containsKey(key) && now < end) { mux.wait(end - now); now = System.currentTimeMillis(); } if (closed) throw new InterruptedException("Session was closed: " + this); return (V) attrs.get(key); } }
/** {@inheritDoc} */ @Override public R get(long timeout, TimeUnit unit) throws GridException { A.ensure(timeout >= 0, "timeout cannot be negative: " + timeout); A.notNull(unit, "unit"); checkValid(); try { long now = System.currentTimeMillis(); long end = timeout == 0 ? Long.MAX_VALUE : now + MILLISECONDS.convert(timeout, unit); // Account for overflow. if (end < 0) end = Long.MAX_VALUE; synchronized (mux) { while (!done && !cancelled && now < end) { mux.wait(end - now); if (!done) now = System.currentTimeMillis(); } if (done) { if (err != null) throw U.cast(err); return res; } if (cancelled) throw new GridFutureCancelledException("Future was cancelled: " + this); throw new GridFutureTimeoutException( "Timeout was reached before computation completed [duration=" + duration() + "ms, timeout=" + unit.toMillis(timeout) + "ms]"); } } catch (InterruptedException e) { throw new GridInterruptedException( "Got interrupted while waiting for future to complete [duration=" + duration() + "ms, timeout=" + unit.toMillis(timeout) + "ms]", e); } }
/** * Starts up grid and checks all provided values for prime. * * @param args Command line arguments, none required but if provided first one should point to the * Spring XML configuration file. See {@code "examples/config/"} for configuration file * examples. * @throws GridException If example execution failed. */ public static void main(String[] args) throws GridException { // Starts grid. Grid grid = args.length == 0 ? G.start() : G.start(args[0]); // Values we want to check for prime. long[] checkVals = {32452841, 32452843, 32452847, 32452849, 236887699, 217645199}; X.println(">>>"); X.println( ">>> Starting to check the following numbers for primes: " + Arrays.toString(checkVals)); try { long start = System.currentTimeMillis(); for (long checkVal : checkVals) { // This method will be executed on the Grid as it is // annotated with @Gridify annotation. Long divisor = GridPrimeChecker.checkPrime(checkVal, 2, checkVal); // If divisor is null, then the number is prime. if (divisor == null) { X.println("Value '" + checkVal + "'is a prime number."); } else { X.println("Value '" + checkVal + "' is divisible by '" + divisor + '\''); } } long totalTime = System.currentTimeMillis() - start; X.println(">>> Total time to calculate all primes (milliseconds): " + totalTime); X.println(">>>"); } finally { // Stops grid. G.stop(grid.name(), true); } }
/** {@inheritDoc} */ @Override public <T> T holdcc(long timeout) { if (ctx != null) { if (job == null) job = ctx.job().activeJob(jobId); // Completed? if (job != null) { if (timeout > 0 && !job.isDone()) { final long endTime = System.currentTimeMillis() + timeout; // Overflow. if (endTime > 0) { ctx.timeout() .addTimeoutObject( new GridTimeoutObject() { private final GridUuid id = GridUuid.randomUuid(); @Override public GridUuid timeoutId() { return id; } @Override public long endTime() { return endTime; } @Override public void onTimeout() { callcc(); } }); } } job.hold(); } } return null; }
/** * Callback to notify that future is finished. Note that if non-{@code null} exception is passed * in the result value will be ignored. * * @param res Optional result. * @param err Optional error. * @return {@code True} if result was set by this call. */ public boolean onDone(@Nullable R res, @Nullable Throwable err) { checkValid(); boolean notify = false; boolean gotDone = false; try { synchronized (mux) { if (!done) { gotDone = true; endTime = System.currentTimeMillis(); this.res = res; this.err = err; done = true; notify = true; mux.notifyAll(); // Notify possibly waiting child classes. return true; } return false; } } finally { if (gotDone) { GridStopwatch w = watch; if (w != null) w.stop(); } if (notify) notifyListeners(); } }
/** * Future adapter. * * @author 2005-2011 Copyright (C) GridGain Systems, Inc. * @version 3.1.1c.19062011 */ public class GridFutureAdapter<R> extends GridMetadataAwareAdapter implements GridFuture<R>, Externalizable { /** Synchronous notification flag. */ private static final boolean SYNC_NOTIFY = U.isFutureNotificationSynchronous(); /** Concurrent notification flag. */ private static final boolean CONCUR_NOTIFY = U.isFutureNotificationConcurrent(); /** Done flag. */ private boolean done; /** Cancelled flag. */ private boolean cancelled; /** Result. */ @GridToStringInclude private R res; /** Error. */ private Throwable err; /** Set to {@code false} on deserialization whenever incomplete future is serialized. */ private boolean valid = true; /** Asynchronous listener. */ private final Set<GridInClosure<? super GridFuture<R>>> lsnrs = new GridLeanSet<GridInClosure<? super GridFuture<R>>>(); /** Creator thread. */ private Thread thread = Thread.currentThread(); /** Mutex. */ private final Object mux = new Object(); /** Context. */ protected GridKernalContext ctx; /** Logger. */ protected GridLogger log; /** Future start time. */ protected final long startTime = System.currentTimeMillis(); /** Synchronous notification flag. */ private volatile boolean syncNotify = SYNC_NOTIFY; /** Concurrent notification flag. */ private volatile boolean concurNotify = CONCUR_NOTIFY; /** Future end time. */ private volatile long endTime; /** Watch. */ protected GridStopwatch watch; /** Empty constructor required for {@link Externalizable}. */ public GridFutureAdapter() { // No-op. } /** @param ctx Kernal context. */ public GridFutureAdapter(GridKernalContext ctx) { assert ctx != null; this.ctx = ctx; log = ctx.log(getClass()); } /** {@inheritDoc} */ @Override public long startTime() { return startTime; } /** {@inheritDoc} */ @Override public long duration() { long endTime = this.endTime; return endTime == 0 ? System.currentTimeMillis() - startTime : endTime - startTime; } /** {@inheritDoc} */ @Override public boolean concurrentNotify() { return concurNotify; } /** {@inheritDoc} */ @Override public void concurrentNotify(boolean concurNotify) { this.concurNotify = concurNotify; } /** {@inheritDoc} */ @Override public boolean syncNotify() { return syncNotify; } /** {@inheritDoc} */ @Override public void syncNotify(boolean syncNotify) { this.syncNotify = syncNotify; } /** * Adds a watch to this future. * * @param name Name of the watch. */ public void addWatch(String name) { assert name != null; watch = W.stopwatch(name); } /** * Adds a watch to this future. * * @param watch Watch to add. */ public void addWatch(GridStopwatch watch) { assert watch != null; this.watch = watch; } /** Checks that future is in usable state. */ protected void checkValid() { if (!valid) throw new IllegalStateException( "Incomplete future was serialized and cannot " + "be used after deserialization."); } /** @return Valid flag. */ protected boolean isValid() { return valid; } /** * Gets internal mutex. * * @return Internal mutex. */ protected Object mutex() { checkValid(); return mux; } /** @return Value of error. */ protected Throwable error() { checkValid(); synchronized (mux) { return err; } } /** @return Value of result. */ protected R result() { checkValid(); synchronized (mux) { return res; } } /** {@inheritDoc} */ @Override public R call() throws Exception { return get(); } /** {@inheritDoc} */ @Override public R get(long timeout) throws GridException { return get(timeout, MILLISECONDS); } /** {@inheritDoc} */ @Override public R get() throws GridException { checkValid(); try { synchronized (mux) { while (!done && !cancelled) mux.wait(); if (done) { if (err != null) throw U.cast(err); return res; } throw new GridFutureCancelledException("Future was cancelled: " + this); } } catch (InterruptedException e) { throw new GridInterruptedException(e); } } /** {@inheritDoc} */ @Override public R get(long timeout, TimeUnit unit) throws GridException { A.ensure(timeout >= 0, "timeout cannot be negative: " + timeout); A.notNull(unit, "unit"); checkValid(); try { long now = System.currentTimeMillis(); long end = timeout == 0 ? Long.MAX_VALUE : now + MILLISECONDS.convert(timeout, unit); // Account for overflow. if (end < 0) end = Long.MAX_VALUE; synchronized (mux) { while (!done && !cancelled && now < end) { mux.wait(end - now); if (!done) now = System.currentTimeMillis(); } if (done) { if (err != null) throw U.cast(err); return res; } if (cancelled) throw new GridFutureCancelledException("Future was cancelled: " + this); throw new GridFutureTimeoutException( "Timeout was reached before computation completed [duration=" + duration() + "ms, timeout=" + unit.toMillis(timeout) + "ms]"); } } catch (InterruptedException e) { throw new GridInterruptedException( "Got interrupted while waiting for future to complete [duration=" + duration() + "ms, timeout=" + unit.toMillis(timeout) + "ms]", e); } } /** {@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()); } } } } /** {@inheritDoc} */ @Override public void stopListenAsync(@Nullable GridInClosure<? super GridFuture<R>>... lsnr) { if (F.isEmpty(lsnr)) synchronized (mux) { lsnrs.clear(); } else synchronized (mux) { lsnrs.removeAll(F.asList(lsnr)); } } /** Notifies all registered listeners. */ private void notifyListeners() { final Collection<GridInClosure<? super GridFuture<R>>> tmp; synchronized (mux) { tmp = new ArrayList<GridInClosure<? super GridFuture<R>>>(lsnrs); } boolean concurNotify = this.concurNotify; boolean syncNotify = this.syncNotify; if (concurNotify) { for (final GridInClosure<? super GridFuture<R>> lsnr : tmp) ctx.closure() .runLocalSafe( new GPR() { @Override public void run() { notifyListener(lsnr); } }, true); } else { // Always notify in the thread different from start thread. if (Thread.currentThread() == thread && !syncNotify) { ctx.closure() .runLocalSafe( new GPR() { @Override public void run() { // Since concurrent notifications are off, we notify // all listeners in one thread. for (GridInClosure<? super GridFuture<R>> lsnr : tmp) notifyListener(lsnr); } }, true); } else { for (GridInClosure<? super GridFuture<R>> lsnr : tmp) notifyListener(lsnr); } } } /** * Notifies single listener. * * @param lsnr Listener. */ private void notifyListener(GridInClosure<? super GridFuture<R>> lsnr) { assert lsnr != null; try { lsnr.apply(this); } catch (IllegalStateException ignore) { U.warn( null, "Failed to notify listener (grid is stopped) [grid=" + ctx.gridName() + ", lsnr=" + lsnr + ']'); } catch (RuntimeException e) { U.error(log, "Failed to notify listener: " + lsnr, e); throw e; } catch (Error e) { U.error(log, "Failed to notify listener: " + lsnr, e); throw e; } } /** * Default no-op implementation that always returns {@code false}. Futures that do support * cancellation should override this method and call {@link #onCancelled()} callback explicitly if * cancellation indeed did happen. */ @Override public boolean cancel() throws GridException { checkValid(); return false; } /** {@inheritDoc} */ @Override public boolean isDone() { // Don't check for "valid" here, as "done" flag can be read // even in invalid state. synchronized (mux) { return done || cancelled; } } /** {@inheritDoc} */ @Override public GridAbsPredicate predicate() { return new PA() { @Override public boolean apply() { return isDone(); } }; } /** {@inheritDoc} */ @Override public boolean isCancelled() { checkValid(); synchronized (mux) { return cancelled; } } /** * Callback to notify that future is finished with {@code null} result. This method must delegate * to {@link #onDone(Object, Throwable)} method. * * @return {@code True} if result was set by this call. */ public final boolean onDone() { return onDone(null, null); } /** * Callback to notify that future is finished. This method must delegate to {@link #onDone(Object, * Throwable)} method. * * @param res Result. * @return {@code True} if result was set by this call. */ public final boolean onDone(@Nullable R res) { return onDone(res, null); } /** * Callback to notify that future is finished. This method must delegate to {@link #onDone(Object, * Throwable)} method. * * @param err Error. * @return {@code True} if result was set by this call. */ public final boolean onDone(@Nullable Throwable err) { return onDone(null, err); } /** * Callback to notify that future is finished. Note that if non-{@code null} exception is passed * in the result value will be ignored. * * @param res Optional result. * @param err Optional error. * @return {@code True} if result was set by this call. */ public boolean onDone(@Nullable R res, @Nullable Throwable err) { checkValid(); boolean notify = false; boolean gotDone = false; try { synchronized (mux) { if (!done) { gotDone = true; endTime = System.currentTimeMillis(); this.res = res; this.err = err; done = true; notify = true; mux.notifyAll(); // Notify possibly waiting child classes. return true; } return false; } } finally { if (gotDone) { GridStopwatch w = watch; if (w != null) w.stop(); } if (notify) notifyListeners(); } } /** * Callback to notify that future is cancelled. * * @return {@code True} if cancel flag was set by this call. */ public boolean onCancelled() { checkValid(); synchronized (mux) { if (cancelled || done) return false; cancelled = true; mux.notifyAll(); // Notify possibly waiting child classes. } return true; } /** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { boolean done; boolean cancelled; Object res; Throwable err; boolean syncNotify; boolean concurNotify; synchronized (mux) { done = this.done; cancelled = this.cancelled; res = this.res; err = this.err; syncNotify = this.syncNotify; concurNotify = this.concurNotify; } out.writeBoolean(done); out.writeBoolean(syncNotify); out.writeBoolean(concurNotify); // Don't write any further if not done, as deserialized future // will be invalid anyways. if (done) { out.writeBoolean(cancelled); out.writeObject(res); out.writeObject(err); } } /** {@inheritDoc} */ @SuppressWarnings({"unchecked"}) @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { boolean done = in.readBoolean(); syncNotify = in.readBoolean(); concurNotify = in.readBoolean(); if (!done) valid = false; else { boolean cancelled = in.readBoolean(); R res = (R) in.readObject(); Throwable err = (Throwable) in.readObject(); synchronized (mux) { this.done = done; this.cancelled = cancelled; this.res = res; this.err = err; } } } /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridFutureAdapter.class, this); } }
/** {@inheritDoc} */ @Override public long duration() { long endTime = this.endTime; return endTime == 0 ? System.currentTimeMillis() - startTime : endTime - startTime; }
/** * @param args Command arguments. * @throws GridException If failed. */ public static void main(String[] args) throws GridException { // Starts grid. Grid grid = args.length == 0 ? G.start() : G.start(args[0]); try { // Create portfolio. GridCredit[] portfolio = new GridCredit[5000]; Random rnd = new Random(); // Generate some test portfolio items. for (int i = 0; i < portfolio.length; i++) { portfolio[i] = new GridCredit( 50000 * rnd.nextDouble(), // Credit amount. rnd.nextInt(1000), // Credit term in days. rnd.nextDouble() / 10, // APR. rnd.nextDouble() / 20 + 0.02 // EDF. ); } // Forecast horizon in days. int horizon = 365; // Number of Monte-Carlo iterations. int iter = 10000; // Percentile. double percentile = 0.95; // Mark the stopwatch. long start = System.currentTimeMillis(); // Calculate credit risk and print it out. // As you can see the grid enabling is completely hidden from the caller // and it is fully transparent to him. In fact, the caller is never directly // aware if method was executed just locally or on the 100s of grid nodes. // Credit risk crdRisk is the minimal amount that creditor has to have // available to cover possible defaults. double crdRisk = grid.reduce( SPREAD, closures(grid.size(), portfolio, horizon, iter, percentile), new R1<Double, Double>() { /** Collected values sum. */ private double sum; /** Collected values count. */ private int count; /** {@inheritDoc} */ @Override public boolean collect(Double e) { sum += e; count++; return true; } /** {@inheritDoc} */ @Override public Double apply() { return sum / count; } }); X.println( "Credit risk [crdRisk=" + crdRisk + ", duration=" + (System.currentTimeMillis() - start) + "ms]"); } // We specifically don't do any error handling here to // simplify the example. Real application may want to // add error handling and application specific recovery. finally { // Stops grid. G.stop(true); } }
/** * Removes obsolete deployments in case of redeploy. * * @param meta Request metadata. * @return List of shares deployment. */ private GridTuple2<Boolean, SharedDeployment> checkRedeploy(GridDeploymentMetadata meta) { assert Thread.holdsLock(mux); SharedDeployment newDep = null; for (List<SharedDeployment> deps : cache.values()) { for (SharedDeployment dep : deps) { if (!dep.isUndeployed() && !dep.isPendingUndeploy()) { long undeployTimeout = ctx.config().getNetworkTimeout(); SharedDeployment doomed = null; // Only check deployments with no participants. if (!dep.hasParticipants()) { // In case of SHARED deployment it is possible to get hear if // unmarshalling happens during undeploy. In this case, we // simply don't do anything. if (dep.deployMode() == CONTINUOUS) { if (dep.existingDeployedClass(meta.className()) != null) { // Change from shared deploy to shared undeploy or user version change. // Simply remove all deployments with no participating nodes. if (meta.deploymentMode() == SHARED || !meta.userVersion().equals(dep.userVersion())) doomed = dep; } } } // If there are participants, we undeploy if class loader ID on some node changed. else if (dep.existingDeployedClass(meta.className()) != null) { GridTuple2<GridUuid, Long> ldr = dep.getClassLoaderId(meta.senderNodeId()); if (ldr != null) { if (!ldr.get1().equals(meta.classLoaderId())) { // If deployed sequence number is less, then schedule for undeployment. if (ldr.get2() < meta.sequenceNumber()) { if (log.isDebugEnabled()) log.debug( "Received request for a class with newer sequence number " + "(will schedule current class for undeployment) [newSeq=" + meta.sequenceNumber() + ", oldSeq=" + ldr.get2() + ", senderNodeId=" + meta.senderNodeId() + ", newClsLdrId=" + meta.classLoaderId() + ", oldClsLdrId=" + ldr.get1() + ']'); doomed = dep; } else if (ldr.get2() > meta.sequenceNumber()) { long time = System.currentTimeMillis() - dep.timestamp(); if (newDep == null && time < ctx.config().getNetworkTimeout()) { // Set undeployTimeout, so the class will be scheduled // for undeployment. undeployTimeout = ctx.config().getNetworkTimeout() - time; if (log.isDebugEnabled()) log.debug( "Received execution request for a stale class (will deploy and " + "schedule undeployment in " + undeployTimeout + "ms) " + "[curSeq=" + ldr.get2() + ", staleSeq=" + meta.sequenceNumber() + ", cls=" + meta.className() + ", senderNodeId=" + meta.senderNodeId() + ", curLdrId=" + ldr.get1() + ", staleLdrId=" + meta.classLoaderId() + ']'); // We got the redeployed class before the old one. // Simply create a temporary deployment for the sender node, // and schedule undeploy for it. newDep = createNewDeployment(meta, false); doomed = newDep; } else { U.warn( log, "Received execution request for a class that has been redeployed " + "(will ignore): " + meta.alias()); if (log.isDebugEnabled()) log.debug( "Received execution request for a class that has been redeployed " + "(will ignore) [alias=" + meta.alias() + ", dep=" + dep + ']'); return F.t(false, null); } } else { U.error( log, "Sequence number does not correspond to class loader ID [seqNum=" + meta.sequenceNumber() + ", dep=" + dep + ']'); return F.t(false, null); } } } } if (doomed != null) { doomed.onUndeployScheduled(); if (log.isDebugEnabled()) log.debug("Deployment was scheduled for undeploy: " + doomed); // Lifespan time. final long endTime = System.currentTimeMillis() + undeployTimeout; // Deployment to undeploy. final SharedDeployment undep = doomed; ctx.timeout() .addTimeoutObject( new GridTimeoutObject() { @Override public GridUuid timeoutId() { return undep.classLoaderId(); } @Override public long endTime() { return endTime < 0 ? Long.MAX_VALUE : endTime; } @Override public void onTimeout() { boolean removed = false; // Hot redeployment. synchronized (mux) { assert undep.isPendingUndeploy(); if (!undep.isUndeployed()) { undep.undeploy(); undep.onRemoved(); removed = true; Collection<SharedDeployment> deps = cache.get(undep.userVersion()); if (deps != null) { for (Iterator<SharedDeployment> i = deps.iterator(); i.hasNext(); ) if (i.next() == undep) i.remove(); if (deps.isEmpty()) cache.remove(undep.userVersion()); } if (log.isInfoEnabled()) log.info( "Undeployed class loader due to deployment mode change, " + "user version change, or hot redeployment: " + undep); } } // Outside synchronization. if (removed) undep.recordUndeployed(null); } }); } } } } if (newDep != null) { List<SharedDeployment> list = F.addIfAbsent(cache, meta.userVersion(), F.<SharedDeployment>newList()); assert list != null; list.add(newDep); } return F.t(true, newDep); }