BufferedItemSourcePool(String poolName, UnpooledByteBufAllocator byteBufAllocator, ResizePolicy resizePolicy, long resizeTimeout, boolean monitored, long monitorTaskInterval, int initialPoolSize, int itemSizeInBytes) { this.poolName = poolName; this.byteBufAllocator = byteBufAllocator; this.resizePolicy = resizePolicy; this.resizeTimeout = resizeTimeout; this.initialPoolSize = initialPoolSize; this.totalPoolSize = new AtomicInteger(); this.estimatedSourceSize = itemSizeInBytes; this.executor = createExecutor(); incrementPoolSize(initialPoolSize); startRecyclerTask(); if (monitored) { startMonitorTask(monitorTaskInterval); } }
public String formattedMetrics(ByteBufAllocatorMetric allocatorMetric) { int capacity = allocatorMetric != null ? 384: 96; // roughly with or without allocator metrics StringBuilder sb = new StringBuilder(capacity) .append('{') .append(" poolName: ").append(getName()) .append(", initialPoolSize: ").append(getInitialSize()) .append(", totalPoolSize: ").append(getTotalSize()) .append(", availablePoolSize: ").append(getAvailableSize()); if (allocatorMetric != null) { sb.append(", allocatorMetric: ").append(allocatorMetric); } return sb.append('}').toString(); }
private ItemSource<ByteBuf> removeInternal(int depth) throws PoolResourceException { try { if (objectPool.isEmpty()) { tryResize(depth); } return objectPool.remove(); } catch (NoSuchElementException e) { tryResize(depth); } // let's go recursive to handle case when resize is smaller than number of threads arriving at the latch return removeInternal(++depth); }
/** * Creates pooled {@link BufferedItemSource} instances * * @param delta number of elements to be pooled */ @Override public final void incrementPoolSize(int delta) { long start = System.currentTimeMillis(); for (int i = 0; i < delta; i++) { incrementPoolSize(); } LOGGER.info("Pool [{}] {} pooled elements added. Total pooled elements: {}. Took: {}ms", getName(), delta, getTotalSize(), (System.currentTimeMillis() - start)); }
@Test public void defaultReleaseCallbackReturnsPooledElement() throws PoolResourceException { // given BufferedItemSourcePool pool = createDefaultTestBufferedItemSourcePool(false); assertEquals(DEFAULT_TEST_INITIAL_POOL_SIZE, pool.getAvailableSize()); pool.incrementPoolSize(); assertEquals(DEFAULT_TEST_INITIAL_POOL_SIZE + 1, pool.getAvailableSize()); // when ItemSource<ByteBuf> itemSource = pool.getPooled(); assertEquals(DEFAULT_TEST_INITIAL_POOL_SIZE, pool.getAvailableSize()); itemSource.release(); // then assertEquals(DEFAULT_TEST_INITIAL_POOL_SIZE + 1, pool.getAvailableSize()); }
@Test public void poolShutdownClearsSourceList() { // given final ScheduledExecutorService mockedExecutor = mock(ScheduledExecutorService.class); BufferedItemSourcePool pool = createDefaultTestBufferedItemSourcePool(false, mockedExecutor); pool.incrementPoolSize(); assertEquals(DEFAULT_TEST_INITIAL_POOL_SIZE + 1, pool.getAvailableSize()); // when pool.shutdown(); // then assertEquals(0, pool.getAvailableSize()); }
@Test public void throwsWhenResizePolicyDoesNotResize() throws PoolResourceException { // given ResizePolicy resizePolicy = mock(ResizePolicy.class); when(resizePolicy.increase(any())).thenReturn(false); BufferedItemSourcePool pool = new BufferedItemSourcePool( DEFAULT_TEST_ITEM_POOL_NAME, byteBufAllocator, resizePolicy, 0, false, DEFAULT_TEST_MONITOR_TASK_INTERVAL, 0, DEFAULT_TEST_ITEM_SIZE_IN_BYTES); expectedException.expect(PoolResourceException.class); expectedException.expectMessage("Unable to resize. Creation of ItemSource was unsuccessful"); // when pool.getPooled(); }
@Test public void metricsPrinterGivenNoAllocatorMetricsContainsPoolStatsOnly() throws PoolResourceException { // given BufferedItemSourcePool pool = createDefaultTestBufferedItemSourcePool(true); BufferedItemSourcePool.PoolMetrics metrics = pool.new PoolMetrics(); // when pool.incrementPoolSize(); pool.getPooled(); String formattedMetrics = metrics.formattedMetrics(null); // then assertTrue(formattedMetrics.contains("poolName: " + DEFAULT_TEST_ITEM_POOL_NAME)); assertTrue(formattedMetrics.contains("initialPoolSize: " + DEFAULT_TEST_INITIAL_POOL_SIZE)); assertTrue(formattedMetrics.contains("totalPoolSize: " + (DEFAULT_TEST_INITIAL_POOL_SIZE + 1))); assertTrue(formattedMetrics.contains("availablePoolSize: " + DEFAULT_TEST_INITIAL_POOL_SIZE)); assertFalse(formattedMetrics.contains("allocatorMetric")); }
ItemSourcePool configuredBufferedItemSourcePool() { return new BufferedItemSourcePool( poolName, new UnpooledByteBufAllocator(false, false, false), resizePolicy, resizeTimeout, monitored, monitorTaskInterval, initialPoolSize, itemSizeInBytes ); }
@Test public void removeReturnFalseInsteadOofThrowingAfterUnderlyingPoolResourceException () { ResizePolicy resizePolicy = mock(ResizePolicy.class); when(resizePolicy.increase(any())).thenThrow(PoolResourceException.class); BufferedItemSourcePool pool = new BufferedItemSourcePool( DEFAULT_TEST_ITEM_POOL_NAME, byteBufAllocator, resizePolicy, 0, false, DEFAULT_TEST_MONITOR_TASK_INTERVAL, 0, DEFAULT_TEST_ITEM_SIZE_IN_BYTES); // when boolean resized = pool.remove(); // then assertFalse(resized); }
@Override public Boolean answer(InvocationOnMock invocation) throws InterruptedException { Thread.sleep(random.nextInt(10) + 10); if (counter.getAndDecrement() <= 0) { pool.incrementPoolSize(2); return true; } failedCounter.incrementAndGet(); return true; } });
Recycler(BufferedItemSourcePool pool, ResizePolicy resizePolicy) { super(pool.getName() + "-Recycler"); this.pool = pool; this.resizePolicy = resizePolicy; }
@Test public void monitoredPoolExecutorFactoryDoesNotReturnNull() { // given BufferedItemSourcePool pool = createDefaultTestBufferedItemSourcePool(true); // when ScheduledExecutorService executor = pool.createExecutor(); // then assertNotNull(executor); }
/** * Elements returned by this method MUST be returned to the pool by calling {@link ItemSource#release()}. * If pool has no more elements, {@link ResizePolicy} will try to create more pooled elements. * * @throws PoolResourceException if {@link ResizePolicy} was not sufficient or didn't create any new elements or thread calling this method was interrupted * @return pooled {@link BufferedItemSource} */ @Override public ItemSource<ByteBuf> getPooled() throws PoolResourceException { return removeInternal(INITIAL_RESIZE_INTERNAL_STACK_DEPTH); }
@Test public void incrementSizeAddsOnePooledElement() throws PoolResourceException { // given BufferedItemSourcePool pool = createDefaultTestBufferedItemSourcePool(0,false); // when pool.incrementPoolSize(); // then assertEquals(1, pool.getAvailableSize()); ItemSource<ByteBuf> itemSource = pool.getPooled(); assertNotNull(itemSource); }
@Test public void throwsWhenNoMorePooledElementsAvailableAndResizePolicyDoesNotCopeWithTheLoad() throws PoolResourceException { // given ResizePolicy resizePolicy = mock(ResizePolicy.class); when(resizePolicy.increase(any())).thenReturn(true); BufferedItemSourcePool pool = new BufferedItemSourcePool( DEFAULT_TEST_ITEM_POOL_NAME, byteBufAllocator, resizePolicy, 0, false, DEFAULT_TEST_MONITOR_TASK_INTERVAL, 0, DEFAULT_TEST_ITEM_SIZE_IN_BYTES); expectedException.expect(PoolResourceException.class); expectedException.expectMessage("has to be reconfigured to handle current load"); expectedException.expectMessage(DEFAULT_TEST_ITEM_POOL_NAME); // when pool.getPooled(); }
/** * Creates pooled {@link BufferedItemSource} instances * * @param delta number of elements to be pooled */ @Override public final void incrementPoolSize(int delta) { long start = System.currentTimeMillis(); for (int i = 0; i < delta; i++) { incrementPoolSize(); } LOGGER.info("Pool [{}] {} pooled elements added. Total pooled elements: {}. Took: {}ms", getName(), delta, getTotalSize(), (System.currentTimeMillis() - start)); }
@Test public void metricsPrinterContainsPoolStats() throws PoolResourceException { // given BufferedItemSourcePool pool = createDefaultTestBufferedItemSourcePool(true); BufferedItemSourcePool.PoolMetrics metrics = pool.new PoolMetrics(); TestPooledByteBufAllocatorMetric allocatorMetrics = new TestPooledByteBufAllocatorMetric(); // when pool.incrementPoolSize(); pool.getPooled(); String formattedMetrics = metrics.formattedMetrics(allocatorMetrics.getDelegate()); // then assertTrue(formattedMetrics.contains("poolName: " + DEFAULT_TEST_ITEM_POOL_NAME)); assertTrue(formattedMetrics.contains("initialPoolSize: " + DEFAULT_TEST_INITIAL_POOL_SIZE)); assertTrue(formattedMetrics.contains("totalPoolSize: " + (DEFAULT_TEST_INITIAL_POOL_SIZE + 1))); assertTrue(formattedMetrics.contains("availablePoolSize: " + DEFAULT_TEST_INITIAL_POOL_SIZE)); assertTrue(formattedMetrics.contains("allocatorMetric")); }
ItemSourcePool configuredBufferedItemSourcePool() { return new BufferedItemSourcePool( poolName, new UnpooledByteBufAllocator(false, false, false), resizePolicy, resizeTimeout, monitored, monitorTaskInterval, initialPoolSize, itemSizeInBytes ); }
Recycler(BufferedItemSourcePool pool, ResizePolicy resizePolicy) { super(pool.getName() + "-Recycler"); this.pool = pool; this.resizePolicy = resizePolicy; }