Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect handling of allocator errors during "warmup" in SimpleDequePool #174

Closed
k-tokarev opened this issue Aug 31, 2023 · 1 comment
Closed
Assignees
Labels
type/bug A general bug warn/regression A regression from a previous release
Milestone

Comments

@k-tokarev
Copy link
Contributor

Expected Behavior

Pool resources should be correctly restored according to size based allocation strategy after allocator problems disappear

Actual Behavior

If allocator can't allocate new resource (emits error in result of acquire) and pool of idle resources is empty then available permits decreasing by minSize-1 (permits for additional "warmup" resources don't return after main resource acquire failure!)

Steps to Reproduce

@Test
void reproCase() {
        val canAllocateResource = new AtomicBoolean(true);
        val allocator = Mono.defer(() ->
            canAllocateResource.get() ?
                Mono.just("value") :
                Mono.error(new IllegalStateException("Can't allocate"))
        );

        val pool = PoolBuilder
            .from(allocator)
            .maxPendingAcquireUnbounded()
            .sizeBetween(10, 10) // Spring Boot R2DBC connections pool default
            .buildPool();

        // New empty pool. No resources allocated yet, but has min-size (10) permits
        assertThat(pool.config().allocationStrategy().estimatePermitCount()).isEqualTo(10);
        assertThat(pool.metrics().idleSize()).isEqualTo(0);

        // Try to acquire one resource. This should trigger pool "warmup" to min-size of resources
        StepVerifier.create(pool.acquire().flatMap(PooledRef::release)).verifyComplete();
        assertThat(pool.config().allocationStrategy().estimatePermitCount()).isEqualTo(0);
        assertThat(pool.metrics().idleSize()).isEqualTo(10);

        // Now allocator will return errors (simulating inaccessible DB server for R2DBC connections pool)
        canAllocateResource.set(false);

        // We have 10 allocated resources in the pool, but they are not valid anymore, so invalidate them
        StepVerifier.create(Flux.range(0, 10).concatMap(ignore -> pool.acquire().flatMap(PooledRef::invalidate)))
            .verifyComplete();
        assertThat(pool.metrics().idleSize()).isEqualTo(0);
        assertThat(pool.config().allocationStrategy().estimatePermitCount()).isEqualTo(10);

        // Now we have empty pool, so it should be warmed up again but allocator still not working
        StepVerifier.create(pool.acquire()).verifyError();
        assertThat(pool.metrics().idleSize()).isEqualTo(0);
        assertThat(pool.config().allocationStrategy().estimatePermitCount()).isEqualTo(10); // Oops!
}

Possible Solution

Naive fix is add .onErrorComplete() or similar error handling to continue Flux processing here:

.startWith(primary.doOnSuccess(__ -> drain()).then())
but I didn't test this fix and don't know possible side effects.

Your Environment

io.projectreactor.addons:reactor-pool:1.0.1

  • Reactor version(s) used: 3.5.9

  • Other relevant libraries versions (eg. netty, ...): no

  • JVM version (java -version):
    openjdk version "17.0.7" 2023-04-18 LTS
    OpenJDK Runtime Environment (build 17.0.7+7-LTS)
    OpenJDK 64-Bit Server VM (build 17.0.7+7-LTS, mixed mode, sharing)

  • OS and version (eg uname -a): Windows 10 Pro 22H2 Build 19045.3324

@reactorbot reactorbot added the ❓need-triage This issue needs triage, hasn't been looked at by a team member yet label Aug 31, 2023
k-tokarev pushed a commit to k-tokarev/reactor-pool that referenced this issue Aug 31, 2023
…source with warming up pool in single reactive process
@pderop pderop self-assigned this Sep 5, 2023
@pderop pderop added type/bug A general bug and removed ❓need-triage This issue needs triage, hasn't been looked at by a team member yet labels Sep 5, 2023
@pderop pderop modified the milestones: 0.2.12, 1.0.2 Sep 5, 2023
k-tokarev pushed a commit to k-tokarev/reactor-pool that referenced this issue Sep 6, 2023
@pderop pderop added the warn/regression A regression from a previous release label Sep 11, 2023
@pderop
Copy link
Contributor

pderop commented Sep 11, 2023

Regression caused by #171 in 1.0.1 version.

@pderop pderop closed this as completed in 9d61d0f Sep 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/bug A general bug warn/regression A regression from a previous release
Projects
None yet
Development

No branches or pull requests

3 participants