[
https://issues.apache.org/jira/browse/GEODE-7531?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16988096#comment-16988096
]
John Blum edited comment on GEODE-7531 at 12/4/19 6:59 PM:
-----------------------------------------------------------
This
[change|https://github.com/apache/geode/blob/rel/v1.10.0/geode-core/src/main/java/org/apache/geode/internal/cache/PoolManagerImpl.java#L169-L174]
(from this
[commit|https://github.com/apache/geode/commit/51dd01cf309f1fccea9fe41e08fab42ed9759e52#diff-8d7c80296713855c7f737671ad251e9a])
would have been better designed and implemented with something like the
following:
1) On the {{Pool}} interface, declare a {{isInUse():boolean}} method.
{code:java}
interface Pool {
boolean isInUse();
...
}
{code}
Then, in the {{PoolManagerImpl}} class, rather than exposing the internal
implementation of {{PoolImpl}} for "how" a {{Pool's}} usage is tracked (i.e.
with an {{attacheCount}} property and an {{AtomicInteger}}, as seen
[here|https://github.com/apache/geode/blob/rel/v1.10.0/geode-core/src/main/java/org/apache/geode/cache/client/internal/PoolImpl.java#L1113-L1141]
and
[here|https://github.com/apache/geode/blob/rel/v1.10.0/geode-core/src/main/java/org/apache/geode/cache/client/internal/PoolImpl.java#L1102-L1108]),
the {{PoolManagerImpl}} can strictly adhere to the interface (this is what is
referred to as "_programming to interfaces_", the "contract", and not the
implementation).
{code:java}
if (pool.isInUse()) {
throw new IllegalStateException("Pool could not be destroyed because it is
still in use!");
}
{code}
Alternatively, and for convenience as well as "_encapsulation_", a method could
be provided on the {{Pool}} interface for assert that a {[Pool}} is not in use.
For instance:
{code:java}
interface Pool {
boolean isInUse();
default void assertNotInUse() {
throw new IllegalStateException("Pools is in use!");
}
}
{code}
The {{assertNotInUse()}} method could be *overloaded* to take a String message
as well. The advantage of having this method on the {{Pool}} is that it allows
the type of Exception thrown to be consistently applied everywhere in code that
the usage of the Pool matters before acting. Additionally, it is assumed that
a {{Pool}} could contain all the information necessary to craft informative and
useful {{Exception}} message.
I'd also argue that the original message stating "how many" Regions is useless
information actually:
{code:java}
throw new IllegalStateException(String.format("Pool could not be destroyed
because it is still in use by %s regions", attachCount));
{code}
For debugging purposes, I'd rather know which Regions (by "name") were still
use the `Pool`.
Furthermore, it is NOT only Regions that use a Pool. It is also CQs and
Functions, etc.
Also, 1 could argue that registering and unregistering a {{Pool}} to be
"managed" by a {{PoolManager}} is an independent concern of whether the
{{Pool}} is in use or not. However, "closing" a {{Pool}} (especially,
prematurely) is certainly a "management" concern for {{Pools}} that are
registered (i.e should be "managed") with a manager (a.k.a. {{PoolManager}}).
was (Author: jblum):
This
[change|https://github.com/apache/geode/blob/rel/v1.10.0/geode-core/src/main/java/org/apache/geode/internal/cache/PoolManagerImpl.java#L169-L174]
(from this
[commit|https://github.com/apache/geode/commit/51dd01cf309f1fccea9fe41e08fab42ed9759e52#diff-8d7c80296713855c7f737671ad251e9a])
would have been better designed and implemented with something like the
following:
1) On the {{Pool}} interface, declare a {{isInUse():boolean}} method.
{code:java}
interface Pool {
boolean isInUse();
...
}
{code}
Then, in the {{PoolManagerImpl}} class, rather than exposing the internal
implementation of {{PoolImpl}} for "how" a {{Pool's}} usage is tracked (i.e.
with an {{attacheCount}} property and an {{AtomicInteger}}, as seen
[here|https://github.com/apache/geode/blob/rel/v1.10.0/geode-core/src/main/java/org/apache/geode/cache/client/internal/PoolImpl.java#L1113-L1141]
and
[here|https://github.com/apache/geode/blob/rel/v1.10.0/geode-core/src/main/java/org/apache/geode/cache/client/internal/PoolImpl.java#L1102-L1108]),
the {{PoolManagerImpl}} can strictly adhere to the interface (this is what is
referred to as "_programming to interfaces_", the "contract", and not the
implementation).
{code:java}
if (pool.isInUse()) {
throw new IllegalStateException("Pool could not be destroyed because it is
still in use!");
}
{code}
I'd also argue that the original message stating "how many" Regions is useless
information actually:
{code:java}
throw new IllegalStateException(String.format("Pool could not be destroyed
because it is still in use by %s regions", attachCount));
{code}
For debugging purposes, I'd rather know which Regions (by "name") were still
use the `Pool`.
Furthermore, it is NOT only Regions that use a Pool. It is also CQs and
Functions, etc.
Also, 1 could argue that registering and unregistering a {{Pool}} to be
"managed" by a {{PoolManager}} is an independent concern of whether the
{{Pool}} is in use or not. However, "closing" a {{Pool}} (especially,
prematurely) is certainly a "management" concern for {{Pools}} that are
registered (i.e should be "managed") with a manager (a.k.a. {{PoolManager}}).
> PoolManagerImpl.unregister(:Pool) naively assumes all Pool object instances
> are PoolImpls
> -----------------------------------------------------------------------------------------
>
> Key: GEODE-7531
> URL: https://issues.apache.org/jira/browse/GEODE-7531
> Project: Geode
> Issue Type: Bug
> Components: client/server
> Affects Versions: 1.10.0
> Environment: Apache Geode based applications on the JVM.
> Reporter: John Blum
> Priority: Blocker
>
> A recent
> [change|https://github.com/apache/geode/blob/rel/v1.10.0/geode-core/src/main/java/org/apache/geode/internal/cache/PoolManagerImpl.java#L169-L174]
> to the {{o.a.g.internal.cache.PoolManagerImpl}} class expects all
> {{o.a.g.cache.client.Pools}} registered with the
> {{o.a.g.cache.client.PoolManager}} to be
> {{o.a.g.cache.client.internal.PoolImp}} objects.
> This is certainly not going to be the case for Unit Tests that properly
> "mock" 1 or more {{Pool}} instances and additionally needs to register the
> mock {{Pool}} instances with the {{PoolManager}}. While the later may not be
> as common for application code, it is more certainly common, and in some
> cases necessary, for framework or tooling code.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)