/** * Set the maximum period a message ack deadline will be extended. Defaults to one hour. * * <p>It is recommended to set this value to a reasonable upper bound of the subscriber time to * process any message. This maximum period avoids messages to be <i>locked</i> by a subscriber * in cases when the ack reply is lost. * * <p>A zero duration effectively disables auto deadline extensions. */ public Builder setMaxAckExtensionPeriod(Duration maxAckExtensionPeriod) { Preconditions.checkArgument(maxAckExtensionPeriod.toMillis() >= 0); this.maxAckExtensionPeriod = maxAckExtensionPeriod; return this; }
@Override public void onSuccess(@Nullable Void result) { if (!isAlive()) { return; } channelReconnectBackoffMillis.set(INITIAL_CHANNEL_RECONNECT_BACKOFF.toMillis()); // The stream was closed. And any case we want to reopen it to continue receiving // messages. initialize(); }
/** * Prevents further mutations and waits for all outstanding mutations to complete. * * @throws BulkMutationFailure If any mutations failed. * @throws InterruptedException If interrupted. * @throws TimeoutException If the outstanding requests don't finish in time. */ public void close(Duration duration) throws InterruptedException, TimeoutException { closed = true; long deadlineMs = System.currentTimeMillis() + duration.toMillis(); synchronized (lock) { while (numOutstanding.get() > 0) { long waitMs = deadlineMs - System.currentTimeMillis(); if (waitMs <= 0) { throw new TimeoutException("Timed out waiting outstanding mutations to finish"); } lock.wait(waitMs); } // numFailures can only be checked after numOutstanding is zero. if (numFailures > 0) { throw new BulkMutationFailure(numFailures); } } }
private void setupDurationBasedPublishAlarm() { if (!activeAlarm.getAndSet(true)) { long delayThresholdMs = getBatchingSettings().getDelayThreshold().toMillis(); logger.log(Level.FINER, "Setting up alarm for the next {0} ms.", delayThresholdMs); currentAlarmFuture = executor.schedule( new Runnable() { @Override public void run() { logger.log(Level.FINER, "Sending messages based on schedule."); activeAlarm.getAndSet(false); publishAllOutstanding(); } }, delayThresholdMs, TimeUnit.MILLISECONDS); } }
/** Initializes a new stream to the backend with backoff. */ private void initStream() { firestoreExecutor.schedule( new Runnable() { @Override public void run() { if (!isActive.get()) { return; } synchronized (Watch.this) { if (!isActive.get()) { return; } Preconditions.checkState(stream == null); current = false; nextAttempt = backoff.createNextAttempt(nextAttempt); stream = firestore.streamRequest(Watch.this, firestore.getClient().listenCallable()); ListenRequest.Builder request = ListenRequest.newBuilder(); request.setDatabase(firestore.getDatabaseName()); request.setAddTarget(target); if (resumeToken != null) { request.getAddTargetBuilder().setResumeToken(resumeToken); } stream.onNext(request.build()); } } }, nextAttempt.getRandomizedRetryDelay().toMillis(), TimeUnit.MILLISECONDS); }
public Builder setBatchingSettings(BatchingSettings batchingSettings) { Preconditions.checkNotNull(batchingSettings); Preconditions.checkNotNull(batchingSettings.getElementCountThreshold()); Preconditions.checkArgument(batchingSettings.getElementCountThreshold() > 0); Preconditions.checkNotNull(batchingSettings.getRequestByteThreshold()); Preconditions.checkArgument(batchingSettings.getRequestByteThreshold() > 0); Preconditions.checkNotNull(batchingSettings.getDelayThreshold()); Preconditions.checkArgument(batchingSettings.getDelayThreshold().toMillis() > 0); this.batchingSettings = batchingSettings; return this; }
private static int waitForProcess(final Process process, Duration timeout) throws InterruptedException, TimeoutException { if (process == null) { return 0; } final SettableFuture<Integer> exitValue = SettableFuture.create(); Thread waiter = new Thread( new Runnable() { @Override public void run() { try { exitValue.set(process.waitFor()); } catch (InterruptedException e) { exitValue.setException(e); } } }); waiter.start(); try { return exitValue.get(timeout.toMillis(), TimeUnit.MILLISECONDS); } catch (ExecutionException e) { if (e.getCause() instanceof InterruptedException) { throw (InterruptedException) e.getCause(); } throw new UncheckedExecutionException(e); } finally { waiter.interrupt(); } }
@Override public void onResponse(StreamingPullResponse response) { channelReconnectBackoffMillis.set(INITIAL_CHANNEL_RECONNECT_BACKOFF.toMillis()); messageDispatcher.processReceivedMessages( response.getReceivedMessagesList(), new Runnable() { @Override public void run() { // Only request more if we're not shutdown. // If errorFuture is done, the stream has either failed or hung up, // and we don't need to request. if (isAlive() && !errorFuture.isDone()) { lock.lock(); try { thisController.request(1); } catch (Exception e) { logger.log(Level.WARNING, "cannot request more messages", e); } finally { lock.unlock(); } } } }); }
long backoffMillis = channelReconnectBackoffMillis.get(); long newBackoffMillis = Math.min(backoffMillis * 2, MAX_CHANNEL_RECONNECT_BACKOFF.toMillis()); channelReconnectBackoffMillis.set(newBackoffMillis);
private void verifyOk(ApiFuture<?> result) { Throwable error = null; try { result.get(FLUSH_PERIOD.plus(DELAY_BUFFER).toMillis(), TimeUnit.MILLISECONDS); } catch (ExecutionException e) { error = e.getCause(); } catch (Throwable t) { error = t; } assertThat(error).isNull(); }
/** * This will advance the reference time of the executor and execute (in the same thread) any * outstanding callable which execution time has passed. */ public void advanceTime(Duration toAdvance) { clock.advance(toAdvance.toMillis(), TimeUnit.MILLISECONDS); work(); }
@SuppressWarnings("ConstantConditions") private void verifyError(ApiFuture<?> result, StatusCode.Code expectedCode) { Throwable error = null; try { result.get(FLUSH_PERIOD.plus(DELAY_BUFFER).toMillis(), TimeUnit.MILLISECONDS); } catch (ExecutionException e) { error = e.getCause(); } catch (Throwable t) { error = t; } assertThat(error).isInstanceOf(ApiException.class); assertThat(((ApiException) error).getStatusCode().getCode()).isEqualTo(expectedCode); }
/** * This method simply calls {@link Thread#sleep(long)}. * * @param delay time to sleep * @throws InterruptedException if any thread has interrupted the current thread */ protected void sleep(Duration delay) throws InterruptedException { if (Duration.ZERO.compareTo(delay) < 0) { Thread.sleep(delay.toMillis()); } } }
/** * This method simply calls {@link Thread#sleep(long)}. * * @param delay time to sleep * @throws InterruptedException if any thread has interrupted the current thread */ protected void sleep(Duration delay) throws InterruptedException { if (Duration.ZERO.compareTo(delay) < 0) { Thread.sleep(delay.toMillis()); } } }
@Override public long millis() { return Jdk8Methods.safeAdd(baseClock.millis(), offset.toMillis()); } @Override
@Override public long millis() { return Jdk8Methods.safeAdd(baseClock.millis(), offset.toMillis()); } @Override
/** {@inheritDoc} */ @Override public void attemptFailed(Throwable error, Duration delay) { Map<String, AttributeValue> attributes = baseAttemptAttributes(); attributes.put("delay ms", AttributeValue.longAttributeValue(delay.toMillis())); populateError(attributes, error); String msg = error != null ? "Attempt failed" : "Operation incomplete"; span.addAnnotation(msg + ", scheduling next attempt", attributes); }
/** {@inheritDoc} */ @Override public void attemptFailed(Throwable error, Duration delay) { Map<String, AttributeValue> attributes = baseAttemptAttributes(); attributes.put("delay ms", AttributeValue.longAttributeValue(delay.toMillis())); populateError(attributes, error); String msg = error != null ? "Attempt failed" : "Operation incomplete"; span.addAnnotation(msg + ", scheduling next attempt", attributes); }
private void sendForwardedPacket(GeonetData data, int sequenceNumber, Instant timeAdded, MacAddress dstMac) { if (!linkLayer.hasEthernetHeader()) { return; } // Forwarding does not work without MAC. double queuingTimeInSeconds = Duration.between(timeAdded, timeInstantNow()).toMillis() * 0.001; double newLifetime = data.destination.maxLifetimeSeconds().get() - queuingTimeInSeconds; byte newHops = (byte)(data.destination.remainingHopLimit().get() - 1); if (newLifetime <= 0 || newHops < 2) { return; } Geobroadcast destination = ((Geobroadcast) data.destination) .withMaxHopLimit(newHops).withMaxLifetimeSeconds(newLifetime); GeonetData newData = data.withDestination(destination); ByteBuffer llPayload = packGeobroadcast(dstMac, senderMac, newData, sequenceNumber); try { sendToLowerLayer(llPayload); } catch (IOException e) { logger.error("Exception in sending forwarded packet", e); } }