public boolean execute(final Runnable job) {
        // If there are no available slots, we won't do anything
        final boolean acquired = slots.tryAcquire();
        if (!acquired) {
            return false;
        }

        try {
            executor.execute(() -> {
                try {
                    job.run();
                } catch (Exception e) {
                    LOG.error("Unhandled job execution error", e);
                } finally {
                    slots.release();
                }
            });
            return true;
        } catch (RejectedExecutionException e) {
            // This should not happen because we always check the semaphore before submitting jobs to the pool
            slots.release();
            return false;
        }
    }
@Test
    public void testExecute() throws Exception {
        final JobWorkerPool pool = new JobWorkerPool("test", 2, new MetricRegistry());

        final CountDownLatch latch1 = new CountDownLatch(1);
        final CountDownLatch latch2 = new CountDownLatch(1);
        final CountDownLatch task1Latch = new CountDownLatch(1);
        final CountDownLatch task2Latch = new CountDownLatch(1);

        // Before we do anything, the number of free slots should be the same as the pool size
        assertThat(pool.freeSlots()).isEqualTo(2);
        assertThat(pool.anySlotsUsed()).isFalse();

        // Execute the first task
        assertThat(pool.execute(() -> {
            var ignored = Uninterruptibles.awaitUninterruptibly(task1Latch, 60, TimeUnit.SECONDS);
            latch1.countDown();
        })).isTrue();

        // The number of free slots should be reduced by one
        assertThat(pool.freeSlots()).isEqualTo(1);
        assertThat(pool.anySlotsUsed()).isTrue();

        // Execute the second task
        assertThat(pool.execute(() -> {
            var ignored = Uninterruptibles.awaitUninterruptibly(task2Latch, 60, TimeUnit.SECONDS);
            latch2.countDown();
        })).isTrue();

        // The number of free slots should be reduced by one
        assertThat(pool.freeSlots()).isEqualTo(0);

        // Since there are no slots left, the tasks shouldn't be executed
        assertThat(pool.execute(() -> {})).isFalse();
        assertThat(pool.freeSlots()).isEqualTo(0);

        // Wait for the first task to finish
        task1Latch.countDown();
        assertThat(latch1.await(60, TimeUnit.SECONDS)).isTrue();

        // Wait for the second task to finish
        task2Latch.countDown();
        assertThat(latch2.await(60, TimeUnit.SECONDS)).isTrue();

        pool.shutdown(Duration.ofSeconds(30));
        assertThat(pool.anySlotsUsed()).isFalse();
    }