/** * Creates a new instance of the BookKeeper log class. * * @param containerId The Id of the Container whose BookKeeperLog to open. * @param zkClient A reference to the CuratorFramework client to use. * @param bookKeeper A reference to the BookKeeper client to use. * @param config Configuration to use. * @param executorService An Executor to use for async operations. */ BookKeeperLog(int containerId, CuratorFramework zkClient, BookKeeper bookKeeper, BookKeeperConfig config, ScheduledExecutorService executorService) { Preconditions.checkArgument(containerId >= 0, "containerId must be a non-negative integer."); this.zkClient = Preconditions.checkNotNull(zkClient, "zkClient"); this.bookKeeper = Preconditions.checkNotNull(bookKeeper, "bookKeeper"); this.config = Preconditions.checkNotNull(config, "config"); this.executorService = Preconditions.checkNotNull(executorService, "executorService"); this.closed = new AtomicBoolean(); this.logNodePath = HierarchyUtils.getPath(containerId, this.config.getZkHierarchyDepth()); this.traceObjectId = String.format("Log[%d]", containerId); this.writes = new WriteQueue(); val retry = createRetryPolicy(this.config.getMaxWriteAttempts(), this.config.getBkWriteTimeoutMillis()); this.writeProcessor = new SequentialAsyncProcessor(this::processWritesSync, retry, this::handleWriteProcessorFailures, this.executorService); this.rolloverProcessor = new SequentialAsyncProcessor(this::rollover, retry, this::handleRolloverFailure, this.executorService); this.metrics = new BookKeeperMetrics.BookKeeperLog(containerId); this.metricReporter = this.executorService.scheduleWithFixedDelay(this::reportMetrics, REPORT_INTERVAL, REPORT_INTERVAL, TimeUnit.MILLISECONDS); }
public void testGetWritesToExecute() { final int ledgerChangeIndex = ITEM_COUNT - 5; val q = new WriteQueue(); val writes = new ArrayList<Write>(); int ledgerId = 0;
final int timeIncrement = 1234 * 1000; // Just over 1ms. AtomicLong time = new AtomicLong(); val q = new WriteQueue(time::get); val writes = new ArrayDeque<Write>(); for (int i = 0; i < ITEM_COUNT; i++) {
/** * Tests the basic functionality of the add() method. */ @Test public void testAdd() { final int timeIncrement = 1234 * 1000; // Just over 1ms. AtomicLong time = new AtomicLong(); val q = new WriteQueue(time::get); val initialStats = q.getStatistics(); Assert.assertEquals("Unexpected getSize on empty queue.", 0, initialStats.getSize()); Assert.assertEquals("Unexpected getAverageFillRate on empty queue.", 0, initialStats.getAverageItemFillRatio(), 0); Assert.assertEquals("Unexpected getExpectedProcessingTimeMillis on empty queue.", 0, initialStats.getExpectedProcessingTimeMillis()); int expectedSize = 0; long firstItemTime = 0; for (int i = 0; i < ITEM_COUNT; i++) { time.addAndGet(timeIncrement); if (i == 0) { firstItemTime = time.get(); } int writeSize = i * 10000; q.add(new Write(new ByteArraySegment(new byte[writeSize]), new TestWriteLedger(i), CompletableFuture.completedFuture(null))); expectedSize += writeSize; val stats = q.getStatistics(); val expectedFillRatio = (double) expectedSize / stats.getSize() / BookKeeperConfig.MAX_APPEND_LENGTH; val expectedProcTime = (time.get() - firstItemTime) / AbstractTimer.NANOS_TO_MILLIS; Assert.assertEquals("Unexpected getSize.", i + 1, stats.getSize()); Assert.assertEquals("Unexpected getAverageFillRate.", expectedFillRatio, stats.getAverageItemFillRatio(), 0.01); Assert.assertEquals("Unexpected getExpectedProcessingTimeMillis.", expectedProcTime, stats.getExpectedProcessingTimeMillis()); } }
val q = new WriteQueue(); val expectedWrites = new ArrayList<Write>(); for (int i = 0; i < ITEM_COUNT; i++) {