forked from netty/netty
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[netty#3218] Add ChannelPool / ChannelPoolMap abstraction and impleme…
…ntations Motivation: Many projects need some kind a Channel/Connection pool implementation. While the protocols are different many things can be shared, so we should provide a generic API and implementation. Modifications: Add ChannelPool / ChannelPoolMap API and implementations. Result: Reusable / Generic pool implementation that users can use.
- Loading branch information
1 parent
6c025b2
commit 56c9883
Showing
17 changed files
with
1,538 additions
and
1 deletion.
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
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
44 changes: 44 additions & 0 deletions
44
transport/src/main/java/io/netty/channel/pool/AbstractChannelPoolHandler.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,44 @@ | ||
/* | ||
* Copyright 2015 The Netty Project | ||
* | ||
* The Netty Project licenses this file to you under the Apache License, | ||
* version 2.0 (the "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.netty.channel.pool; | ||
|
||
import io.netty.channel.Channel; | ||
|
||
/** | ||
* A skeletal {@link ChannelPoolHandler} implementation. | ||
*/ | ||
public abstract class AbstractChannelPoolHandler implements ChannelPoolHandler { | ||
|
||
/** | ||
* NOOP implementation, sub-classes may override this. | ||
* | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public void channelAcquired(@SuppressWarnings("unused") Channel ch) throws Exception { | ||
// NOOP | ||
} | ||
|
||
/** | ||
* NOOP implementation, sub-classes may override this. | ||
* | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public void channelReleased(@SuppressWarnings("unused") Channel ch) throws Exception { | ||
// NOOP | ||
} | ||
} |
100 changes: 100 additions & 0 deletions
100
transport/src/main/java/io/netty/channel/pool/AbstractChannelPoolMap.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,100 @@ | ||
/* | ||
* Copyright 2015 The Netty Project | ||
* | ||
* The Netty Project licenses this file to you under the Apache License, | ||
* version 2.0 (the "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.netty.channel.pool; | ||
|
||
import io.netty.util.internal.PlatformDependent; | ||
import io.netty.util.internal.ReadOnlyIterator; | ||
|
||
import java.io.Closeable; | ||
import java.util.Iterator; | ||
import java.util.Map.Entry; | ||
import java.util.concurrent.ConcurrentMap; | ||
|
||
import static io.netty.util.internal.ObjectUtil.checkNotNull; | ||
|
||
/** | ||
* A skeletal {@link ChannelPoolMap} implementation. To find the right {@link ChannelPool} | ||
* the {@link Object#hashCode()} and {@link Object#equals(Object)} is used. | ||
*/ | ||
public abstract class AbstractChannelPoolMap<K, P extends ChannelPool> | ||
implements ChannelPoolMap<K, P>, Iterable<Entry<K, P>>, Closeable { | ||
private final ConcurrentMap<K, P> map = PlatformDependent.newConcurrentHashMap(); | ||
|
||
@Override | ||
public final P get(K key) { | ||
P pool = map.get(checkNotNull(key, "key")); | ||
if (pool == null) { | ||
pool = newPool(key); | ||
P old = map.putIfAbsent(key, pool); | ||
if (old != null) { | ||
// We need to destroy the newly created pool as we not use it. | ||
pool.close(); | ||
pool = old; | ||
} | ||
} | ||
return pool; | ||
} | ||
/** | ||
* Remove the {@link ChannelPool} from this {@link AbstractChannelPoolMap}. Returns {@code true} if removed, | ||
* {@code false} otherwise. | ||
* | ||
* Please note that {@code null} keys are not allowed. | ||
*/ | ||
public final boolean remove(K key) { | ||
P pool = map.remove(checkNotNull(key, "key")); | ||
if (pool != null) { | ||
pool.close(); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
@Override | ||
public final Iterator<Entry<K, P>> iterator() { | ||
return new ReadOnlyIterator<Entry<K, P>>(map.entrySet().iterator()); | ||
} | ||
|
||
/** | ||
* Returns the number of {@link ChannelPool}s currently in this {@link AbstractChannelPoolMap}. | ||
*/ | ||
public final int size() { | ||
return map.size(); | ||
} | ||
|
||
/** | ||
* Returns {@code true} if the {@link AbstractChannelPoolMap} is empty, otherwise {@code false}. | ||
*/ | ||
public final boolean isEmpty() { | ||
return map.isEmpty(); | ||
} | ||
|
||
@Override | ||
public final boolean contains(K key) { | ||
return map.containsKey(checkNotNull(key, "key")); | ||
} | ||
|
||
/** | ||
* Called once a new {@link ChannelPool} needs to be created as non exists yet for the {@code key}. | ||
*/ | ||
protected abstract P newPool(K key); | ||
|
||
@Override | ||
public final void close() { | ||
for (K key: map.keySet()) { | ||
remove(key); | ||
} | ||
} | ||
} |
47 changes: 47 additions & 0 deletions
47
transport/src/main/java/io/netty/channel/pool/ChannelHealthChecker.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,47 @@ | ||
/* | ||
* Copyright 2015 The Netty Project | ||
* | ||
* The Netty Project licenses this file to you under the Apache License, | ||
* version 2.0 (the "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.netty.channel.pool; | ||
|
||
import io.netty.channel.Channel; | ||
import io.netty.channel.EventLoop; | ||
import io.netty.util.concurrent.Future; | ||
import io.netty.util.concurrent.Promise; | ||
|
||
/** | ||
* Called before a {@link Channel} will be returned via {@link ChannelPool#acquire()} or | ||
* {@link ChannelPool#acquire(Promise)}. | ||
*/ | ||
public interface ChannelHealthChecker { | ||
|
||
/** | ||
* {@link ChannelHealthChecker} implementation that checks if {@link Channel#isActive()} returns {@code true}. | ||
*/ | ||
ChannelHealthChecker ACTIVE = new ChannelHealthChecker() { | ||
@Override | ||
public Future<Boolean> isHealthy(Channel channel) { | ||
EventLoop loop = channel.eventLoop(); | ||
return channel.isActive()? loop.newSucceededFuture(Boolean.TRUE) : loop.newSucceededFuture(Boolean.FALSE); | ||
} | ||
}; | ||
|
||
/** | ||
* Check if the given channel is healthy which means it can be used. The returned {@link Future} is notified once | ||
* the check is complete. If notified with {@link Boolean#TRUE} it can be used {@link Boolean#FALSE} otherwise. | ||
* | ||
* This method will be called by the {@link EventLoop} of the {@link Channel}. | ||
*/ | ||
Future<Boolean> isHealthy(Channel channel); | ||
} |
56 changes: 56 additions & 0 deletions
56
transport/src/main/java/io/netty/channel/pool/ChannelPool.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,56 @@ | ||
/* | ||
* Copyright 2015 The Netty Project | ||
* | ||
* The Netty Project licenses this file to you under the Apache License, | ||
* version 2.0 (the "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.netty.channel.pool; | ||
|
||
import io.netty.channel.Channel; | ||
import io.netty.util.concurrent.Future; | ||
import io.netty.util.concurrent.Promise; | ||
|
||
import java.io.Closeable; | ||
import java.io.IOException; | ||
|
||
/** | ||
* Allows to acquire and release {@link Channel} and so act as a pool of these. | ||
*/ | ||
public interface ChannelPool extends Closeable { | ||
|
||
/** | ||
* Acquire a {@link Channel} from this {@link ChannelPool}. The returned {@link Future} is notified once | ||
* the acquire is successful and failed otherwise. | ||
*/ | ||
Future<Channel> acquire(); | ||
|
||
/** | ||
* Acquire a {@link Channel} from this {@link ChannelPool}. The given {@link Promise} is notified once | ||
* the acquire is successful and failed otherwise. | ||
*/ | ||
Future<Channel> acquire(Promise<Channel> promise); | ||
|
||
/** | ||
* Release a {@link Channel} back to this {@link ChannelPool}. The returned {@link Future} is notified once | ||
* the release is successful and failed otherwise. When failed the {@link Channel} will automatically closed. | ||
*/ | ||
Future<Void> release(Channel channel); | ||
|
||
/** | ||
* Release a {@link Channel} back to this {@link ChannelPool}. The given {@link Promise} is notified once | ||
* the release is successful and failed otherwise. When failed the {@link Channel} will automatically closed. | ||
*/ | ||
Future<Void> release(Channel channel, Promise<Void> promise); | ||
|
||
@Override | ||
void close(); | ||
} |
48 changes: 48 additions & 0 deletions
48
transport/src/main/java/io/netty/channel/pool/ChannelPoolHandler.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,48 @@ | ||
/* | ||
* Copyright 2015 The Netty Project | ||
* | ||
* The Netty Project licenses this file to you under the Apache License, | ||
* version 2.0 (the "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at: | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.netty.channel.pool; | ||
|
||
import io.netty.channel.Channel; | ||
import io.netty.channel.EventLoop; | ||
import io.netty.util.concurrent.Promise; | ||
|
||
/** | ||
* Handler which is called for various actions done by the {@link ChannelPool}. | ||
*/ | ||
public interface ChannelPoolHandler { | ||
/** | ||
* Called once a {@link Channel} was released by calling {@link ChannelPool#release(Channel)} or | ||
* {@link ChannelPool#release(Channel, Promise)}. | ||
* | ||
* This method will be called by the {@link EventLoop} of the {@link Channel}. | ||
*/ | ||
void channelReleased(Channel ch) throws Exception; | ||
|
||
/** | ||
* Called once a {@link Channel} was acquired by calling {@link ChannelPool#acquire()} or | ||
* {@link ChannelPool#acquire(Promise)}. | ||
* | ||
* This method will be called by the {@link EventLoop} of the {@link Channel}. | ||
*/ | ||
void channelAcquired(Channel ch) throws Exception; | ||
|
||
/** | ||
* Called once a new {@link Channel} is created in the {@link ChannelPool}. | ||
* | ||
* This method will be called by the {@link EventLoop} of the {@link Channel}. | ||
*/ | ||
void channelCreated(Channel ch) throws Exception; | ||
} |
Oops, something went wrong.