Skip to content

Commit dba307a

Browse files
sergebggaryrussell
authored andcommitted
GH-3143: Fix simple pool resizing
Resolves spring-projects/spring-amqp#1142 Resize down does not work when not enough already allocated to match the reduction. Improved SimplePool test cases and fixed code style Fixed code style GH-3143: Test Polishing - use preferred assertJ expected exception checking - add a test for reducing a partially allocated pool - check active counts
1 parent 7a3a8a4 commit dba307a

File tree

2 files changed

+106
-4
lines changed

2 files changed

+106
-4
lines changed

spring-integration-core/src/main/java/org/springframework/integration/util/SimplePool.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
* demand up to the limit.
3737
*
3838
* @author Gary Russell
39+
* @author Sergey Bogatyrev
3940
* @since 2.2
4041
*
4142
*/
@@ -102,11 +103,9 @@ public synchronized void setPoolSize(int poolSize) {
102103
break;
103104
}
104105
T item = this.available.poll();
105-
if (item == null) {
106-
this.permits.release();
107-
break;
106+
if (item != null) {
107+
doRemoveItem(item);
108108
}
109-
doRemoveItem(item);
110109
this.poolSize.decrementAndGet();
111110
delta++;
112111
}

spring-integration-core/src/test/java/org/springframework/integration/util/SimplePoolTests.java

+103
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
package org.springframework.integration.util;
1818

1919
import static org.assertj.core.api.Assertions.assertThat;
20+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
2021
import static org.assertj.core.api.Assertions.fail;
2122

23+
import java.util.ArrayList;
2224
import java.util.HashSet;
25+
import java.util.List;
2326
import java.util.Set;
2427
import java.util.concurrent.Semaphore;
2528
import java.util.concurrent.atomic.AtomicBoolean;
@@ -30,6 +33,7 @@
3033

3134
/**
3235
* @author Gary Russell
36+
* @author Sergey Bogatyrev
3337
* @since 2.2
3438
*
3539
*/
@@ -147,6 +151,105 @@ public void testDoubleReturn() {
147151
assertThat(permits.availablePermits()).isEqualTo(2);
148152
}
149153

154+
@Test
155+
public void testSizeUpdateIfNotAllocated() {
156+
SimplePool<String> pool = stringPool(10, new HashSet<>(), new AtomicBoolean());
157+
pool.setWaitTimeout(0);
158+
pool.setPoolSize(5);
159+
assertThat(pool.getPoolSize()).isEqualTo(5);
160+
161+
// allocating all available items to check permits
162+
Set<String> allocatedItems = new HashSet<>();
163+
for (int i = 0; i < 5; i++) {
164+
allocatedItems.add(pool.getItem());
165+
}
166+
assertThat(allocatedItems).hasSize(5);
167+
168+
// no more items can be allocated (indirect check of permits)
169+
assertThatExceptionOfType(PoolItemNotAvailableException.class).isThrownBy(() -> pool.getItem());
170+
}
171+
172+
@Test
173+
public void testSizeUpdateIfPartiallyAllocated() {
174+
SimplePool<String> pool = stringPool(10, new HashSet<>(), new AtomicBoolean());
175+
pool.setWaitTimeout(0);
176+
List<String> allocated = new ArrayList<>();
177+
for (int i = 0; i < 10; i++) {
178+
allocated.add(pool.getItem());
179+
}
180+
181+
// release only 2 items
182+
for (int i = 0; i < 2; i++) {
183+
pool.releaseItem(allocated.get(i));
184+
}
185+
186+
// trying to reduce pool size
187+
pool.setPoolSize(5);
188+
189+
// at this moment the actual pool size can be reduced only partially, because
190+
// only 2 items have been released, so 8 items are in use
191+
assertThat(pool.getPoolSize()).isEqualTo(8);
192+
assertThat(pool.getAllocatedCount()).isEqualTo(8);
193+
assertThat(pool.getIdleCount()).isEqualTo(0);
194+
assertThat(pool.getActiveCount()).isEqualTo(8);
195+
196+
// releasing 3 items
197+
for (int i = 2; i < 5; i++) {
198+
pool.releaseItem(allocated.get(i));
199+
}
200+
201+
// now pool size should be reduced
202+
assertThat(pool.getPoolSize()).isEqualTo(5);
203+
assertThat(pool.getAllocatedCount()).isEqualTo(5);
204+
assertThat(pool.getIdleCount()).isEqualTo(0);
205+
assertThat(pool.getActiveCount()).isEqualTo(5);
206+
207+
// no more items can be allocated (indirect check of permits)
208+
assertThatExceptionOfType(PoolItemNotAvailableException.class).isThrownBy(() -> pool.getItem());
209+
}
210+
211+
@Test
212+
public void testSizeUpdateIfFullyAllocated() {
213+
SimplePool<String> pool = stringPool(10, new HashSet<>(), new AtomicBoolean());
214+
pool.setWaitTimeout(0);
215+
List<String> allocated = new ArrayList<>();
216+
for (int i = 0; i < 10; i++) {
217+
allocated.add(pool.getItem());
218+
}
219+
220+
// trying to reduce pool size
221+
pool.setPoolSize(5);
222+
223+
// at this moment the actual pool size cannot be reduced - all in use
224+
assertThat(pool.getPoolSize()).isEqualTo(10);
225+
assertThat(pool.getAllocatedCount()).isEqualTo(10);
226+
assertThat(pool.getIdleCount()).isEqualTo(0);
227+
assertThat(pool.getActiveCount()).isEqualTo(10);
228+
229+
// releasing 5 items
230+
for (int i = 0; i < 5; i++) {
231+
pool.releaseItem(allocated.get(i));
232+
}
233+
234+
// now pool size should be reduced
235+
assertThat(pool.getPoolSize()).isEqualTo(5);
236+
assertThat(pool.getAllocatedCount()).isEqualTo(5);
237+
assertThat(pool.getIdleCount()).isEqualTo(0);
238+
assertThat(pool.getActiveCount()).isEqualTo(5);
239+
240+
// no more items can be allocated (indirect check of permits)
241+
assertThatExceptionOfType(PoolItemNotAvailableException.class).isThrownBy(() -> pool.getItem());
242+
243+
// releasing remaining items
244+
for (int i = 5; i < 10; i++) {
245+
pool.releaseItem(allocated.get(i));
246+
}
247+
248+
assertThat(pool.getPoolSize()).isEqualTo(5);
249+
assertThat(pool.getAllocatedCount()).isEqualTo(5);
250+
assertThat(pool.getIdleCount()).isEqualTo(5);
251+
assertThat(pool.getActiveCount()).isEqualTo(0);
252+
}
150253

151254
private SimplePool<String> stringPool(int size, final Set<String> strings,
152255
final AtomicBoolean stale) {

0 commit comments

Comments
 (0)