package com.jivesoftware.os.amzabot.deployable.bot; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.jivesoftware.os.amza.api.PartitionClientProvider; import com.jivesoftware.os.amza.api.partition.Consistency; import com.jivesoftware.os.amza.api.partition.Durability; import com.jivesoftware.os.amzabot.deployable.AmzaBotConfig; import com.jivesoftware.os.amzabot.deployable.AmzaBotService; import com.jivesoftware.os.amzabot.deployable.AmzaKeyClearingHousePool; import com.jivesoftware.os.jive.utils.ordered.id.ConstantWriterIdProvider; import com.jivesoftware.os.jive.utils.ordered.id.OrderIdProvider; import com.jivesoftware.os.jive.utils.ordered.id.OrderIdProviderImpl; import com.jivesoftware.os.mlogger.core.MetricLogger; import com.jivesoftware.os.mlogger.core.MetricLoggerFactory; import com.jivesoftware.os.routing.bird.deployable.InstanceConfig; import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; public class AmzaBotCoalmineService { private static final MetricLogger LOG = MetricLoggerFactory.getLogger(); private final InstanceConfig instanceConfig; private final AmzaBotConfig amzaBotConfig; private final AmzaBotCoalmineConfig amzaBotCoalmineConfig; private final PartitionClientProvider partitionClientProvider; private final AmzaKeyClearingHousePool amzaKeyClearingHousePool; private final AtomicBoolean running = new AtomicBoolean(false); private final ScheduledExecutorService processor = Executors.newSingleThreadScheduledExecutor( new ThreadFactoryBuilder().setNameFormat("amzabot-coalmine-%d").build()); public AmzaBotCoalmineService(InstanceConfig instanceConfig, AmzaBotConfig amzaBotConfig, AmzaBotCoalmineConfig amzaBotCoalmineConfig, PartitionClientProvider partitionClientProvider, AmzaKeyClearingHousePool amzaKeyClearingHousePool) { this.instanceConfig = instanceConfig; this.amzaBotConfig = amzaBotConfig; this.amzaBotCoalmineConfig = amzaBotCoalmineConfig; this.partitionClientProvider = partitionClientProvider; this.amzaKeyClearingHousePool = amzaKeyClearingHousePool; } public AmzaBotCoalminer newMinerWithConfig(AmzaBotCoalmineConfig config) throws Exception { LOG.info("Coalmine capacity: {}", config.getCoalmineCapacity()); LOG.info("Canary size threshold: {}", config.getCanarySizeThreshold()); LOG.info("Hesitation: {}ms", config.getHesitationMs()); LOG.info("Durability: {}", config.getDurability()); LOG.info("Consistency: {}", config.getConsistency()); LOG.info("Ring size: {}", config.getRingSize()); LOG.info("Client timestamp: {}", config.getClientOrdering()); OrderIdProvider orderIdProvider = () -> -1L; if (config.getClientOrdering()) { orderIdProvider = new OrderIdProviderImpl( new ConstantWriterIdProvider(instanceConfig.getInstanceName())); } return new AmzaBotCoalminer( config, new AmzaBotService(amzaBotConfig, partitionClientProvider, orderIdProvider, Durability.valueOf(config.getDurability()), Consistency.valueOf(config.getConsistency()), "amzabot-coalmine-" + UUID.randomUUID().toString(), config.getRingSize(), 0, 0), amzaKeyClearingHousePool); } public AmzaBotCoalminer newMiner() throws Exception { return newMinerWithConfig(amzaBotCoalmineConfig); } public void start() { if (!amzaBotCoalmineConfig.getEnabled()) { LOG.warn("Not starting coalminer service; not enabled."); return; } LOG.info("Frequency {}ms", amzaBotCoalmineConfig.getFrequencyMs()); running.set(true); processor.scheduleWithFixedDelay(() -> { if (running.get()) { LOG.info("Scheduling coalmine thread"); try { ExecutorService executor = Executors.newSingleThreadExecutor( new ThreadFactoryBuilder().setNameFormat("amzabot-coalmine-%d").build()); executor.submit(newMiner()); } catch (Exception e) { LOG.error("Error occurred scheduling coalmine.", e); } } }, 0, amzaBotCoalmineConfig.getFrequencyMs(), TimeUnit.MILLISECONDS); } public void stop() throws InterruptedException { running.set(false); Thread.sleep(amzaBotCoalmineConfig.getHesitationMs()); processor.shutdownNow(); } }