-
Notifications
You must be signed in to change notification settings - Fork 992
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use RefCounters to track open resources #196
The DefaultEventLoopProvider tracks now resources using a ref-counter mechanism. Resources in use are no longer closed by the DefaultEventLoopProvider when calling release(...). Only the last call to release(...) causes the resource to be shut down.
- Loading branch information
Showing
3 changed files
with
160 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
src/test/java/com/lambdaworks/redis/RedisClientTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package com.lambdaworks.redis; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import java.lang.reflect.Field; | ||
import java.util.Map; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import org.junit.Test; | ||
|
||
import com.lambdaworks.redis.resource.ClientResources; | ||
import com.lambdaworks.redis.resource.DefaultClientResources; | ||
import com.lambdaworks.redis.resource.DefaultEventLoopGroupProvider; | ||
import io.netty.util.concurrent.EventExecutorGroup; | ||
|
||
/** | ||
* @author <a href="mailto:[email protected]">Mark Paluch</a> | ||
*/ | ||
public class RedisClientTest { | ||
|
||
@Test | ||
public void reuseClientConnections() throws Exception { | ||
|
||
// given | ||
DefaultClientResources clientResources = DefaultClientResources.create(); | ||
Map<Class<? extends EventExecutorGroup>, EventExecutorGroup> eventLoopGroups = getExecutors(clientResources); | ||
|
||
RedisClient redisClient1 = newClient(clientResources); | ||
RedisClient redisClient2 = newClient(clientResources); | ||
connectAndClose(redisClient1); | ||
connectAndClose(redisClient2); | ||
|
||
// when | ||
EventExecutorGroup executor = eventLoopGroups.values().iterator().next(); | ||
redisClient1.shutdown(0, 0, TimeUnit.MILLISECONDS); | ||
|
||
// then | ||
connectAndClose(redisClient2); | ||
|
||
clientResources.shutdown(0, 0, TimeUnit.MILLISECONDS).get(); | ||
|
||
assertThat(eventLoopGroups).isEmpty(); | ||
assertThat(executor.isShuttingDown()).isTrue(); | ||
assertThat(clientResources.eventExecutorGroup().isShuttingDown()).isTrue(); | ||
} | ||
|
||
@Test | ||
public void reuseClientConnectionsShutdownTwoClients() throws Exception { | ||
|
||
// given | ||
DefaultClientResources clientResources = DefaultClientResources.create(); | ||
Map<Class<? extends EventExecutorGroup>, EventExecutorGroup> eventLoopGroups = getExecutors(clientResources); | ||
|
||
RedisClient redisClient1 = newClient(clientResources); | ||
RedisClient redisClient2 = newClient(clientResources); | ||
connectAndClose(redisClient1); | ||
connectAndClose(redisClient2); | ||
|
||
// when | ||
EventExecutorGroup executor = eventLoopGroups.values().iterator().next(); | ||
|
||
redisClient1.shutdown(0, 0, TimeUnit.MILLISECONDS); | ||
assertThat(executor.isShutdown()).isFalse(); | ||
connectAndClose(redisClient2); | ||
redisClient1.shutdown(0, 0, TimeUnit.MILLISECONDS); | ||
|
||
// then | ||
assertThat(eventLoopGroups).isEmpty(); | ||
assertThat(executor.isShutdown()).isTrue(); | ||
assertThat(clientResources.eventExecutorGroup().isShuttingDown()).isFalse(); | ||
|
||
// cleanup | ||
clientResources.shutdown(0, 0, TimeUnit.MILLISECONDS).get(); | ||
assertThat(clientResources.eventExecutorGroup().isShuttingDown()).isTrue(); | ||
} | ||
|
||
@Test | ||
public void managedClientResources() throws Exception { | ||
|
||
// given | ||
RedisClient redisClient1 = RedisClient.create(RedisURI.create(TestSettings.host(), TestSettings.port())); | ||
ClientResources clientResources = redisClient1.getResources(); | ||
Map<Class<? extends EventExecutorGroup>, EventExecutorGroup> eventLoopGroups = getExecutors(clientResources); | ||
connectAndClose(redisClient1); | ||
|
||
// when | ||
EventExecutorGroup executor = eventLoopGroups.values().iterator().next(); | ||
|
||
redisClient1.shutdown(0, 0, TimeUnit.MILLISECONDS); | ||
|
||
// then | ||
assertThat(eventLoopGroups).isEmpty(); | ||
assertThat(executor.isShuttingDown()).isTrue(); | ||
assertThat(clientResources.eventExecutorGroup().isShuttingDown()).isTrue(); | ||
} | ||
|
||
private void connectAndClose(RedisClient client) { | ||
client.connect().close(); | ||
} | ||
|
||
private RedisClient newClient(DefaultClientResources clientResources) { | ||
return RedisClient.create(clientResources, RedisURI.create(TestSettings.host(), TestSettings.port())); | ||
} | ||
|
||
private Map<Class<? extends EventExecutorGroup>, EventExecutorGroup> getExecutors(ClientResources clientResources) | ||
throws Exception { | ||
Field eventLoopGroupsField = DefaultEventLoopGroupProvider.class.getDeclaredField("eventLoopGroups"); | ||
eventLoopGroupsField.setAccessible(true); | ||
return (Map) eventLoopGroupsField.get(clientResources.eventLoopGroupProvider()); | ||
} | ||
} |