private void setUpStatsExport() { // Export the value. Stats.export(name, value); // Export the rate of this value. Stats.export(Rate.of(name + "_per_sec", value).build()); }
@Override protected void configure() { // Don't worry about clean shutdown, these can be daemon and cleanup-free. final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor( ASYNC_WORKER_THREADS.get(), new ThreadFactoryBuilder().setNameFormat("AsyncProcessor-%d").setDaemon(true).build()); Stats.exportSize("timeout_queue_size", executor.getQueue()); Stats.export( new StatImpl<Long>("async_tasks_completed") { @Override public Long read() { return executor.getCompletedTaskCount(); } }); // AsyncModule itself is not a subclass of PrivateModule because TaskEventModule internally uses // a MultiBinder, which cannot span multiple injectors. binder() .install( new PrivateModule() { @Override protected void configure() { bind(new TypeLiteral<Amount<Long, Time>>() {}) .toInstance(TRANSIENT_TASK_STATE_TIMEOUT.get()); bind(ScheduledExecutorService.class).toInstance(executor); bind(TaskTimeout.class).in(Singleton.class); requireBinding(StatsProvider.class); expose(TaskTimeout.class); } }); PubsubEventModule.bindSubscriber(binder(), TaskTimeout.class); binder() .install( new PrivateModule() { @Override protected void configure() { bind(TaskGroupsSettings.class) .toInstance( new TaskGroupsSettings( new TruncatedBinaryBackoff( INITIAL_SCHEDULE_DELAY.get(), MAX_SCHEDULE_DELAY.get()), RateLimiter.create(MAX_SCHEDULE_ATTEMPTS_PER_SEC.get()))); bind(RescheduleCalculatorImpl.RescheduleCalculatorSettings.class) .toInstance( new RescheduleCalculatorImpl.RescheduleCalculatorSettings( new TruncatedBinaryBackoff( INITIAL_FLAPPING_DELAY.get(), MAX_FLAPPING_DELAY.get()), FLAPPING_THRESHOLD.get(), MAX_RESCHEDULING_DELAY.get())); bind(RescheduleCalculator.class) .to(RescheduleCalculatorImpl.class) .in(Singleton.class); if (ENABLE_PREEMPTOR.get()) { bind(PREEMPTOR_KEY).to(PreemptorImpl.class); bind(PreemptorImpl.class).in(Singleton.class); LOG.info("Preemptor Enabled."); } else { bind(PREEMPTOR_KEY).toInstance(NULL_PREEMPTOR); LOG.warning("Preemptor Disabled."); } expose(PREEMPTOR_KEY); bind(new TypeLiteral<Amount<Long, Time>>() {}) .annotatedWith(PreemptionDelay.class) .toInstance(PREEMPTION_DELAY.get()); bind(TaskGroups.class).in(Singleton.class); expose(TaskGroups.class); } }); bindTaskScheduler(binder(), PREEMPTOR_KEY, RESERVATION_DURATION.get()); PubsubEventModule.bindSubscriber(binder(), TaskGroups.class); binder() .install( new PrivateModule() { @Override protected void configure() { bind(OfferReturnDelay.class).to(RandomJitterReturnDelay.class); bind(ScheduledExecutorService.class).toInstance(executor); bind(OfferQueue.class).to(OfferQueueImpl.class); bind(OfferQueueImpl.class).in(Singleton.class); expose(OfferQueue.class); } }); PubsubEventModule.bindSubscriber(binder(), OfferQueue.class); binder() .install( new PrivateModule() { @Override protected void configure() { // TODO(ksweeney): Create a configuration validator module so this can be injected. // TODO(William Farner): Revert this once large task counts is cheap ala // hierarchichal store bind(Integer.class).annotatedWith(PruneThreshold.class).toInstance(100); bind(new TypeLiteral<Amount<Long, Time>>() {}) .annotatedWith(PruneThreshold.class) .toInstance(HISTORY_PRUNE_THRESHOLD.get()); bind(ScheduledExecutorService.class).toInstance(executor); bind(HistoryPruner.class).in(Singleton.class); expose(HistoryPruner.class); } }); PubsubEventModule.bindSubscriber(binder(), HistoryPruner.class); }