[
https://issues.apache.org/jira/browse/ZOOKEEPER-2141?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15216993#comment-15216993
]
Edward Ribeiro commented on ZOOKEEPER-2141:
-------------------------------------------
Hi [~adammilnesmith] and [~fournc], I am *really* sorry for only having
(limited) time to review/check this patch after it has been committed to trunk.
:( So, please, take it more like a couple of highlights, if you like.
The patch is really cool, and great work, but I have seen some things that
raised some questions I would like to point, plus a couple of minor (i.e.,
irrelevant) issues.
1. The piece of code below, from {{ReferenceCountedACLCache}}, worried me a bit:
{code}
public synchronized boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ReferenceCountedACLCache that = (ReferenceCountedACLCache) o;
synchronized (that) {
if (aclIndex != that.aclIndex) return false;
}
(...)
{code}
See, we are acquiring a lock of object {{foo1}} and then acquiring the lock of
object {{foo2}} ({{that}}, in this case) inside it. My question is: wouldn't
this potentially leads to a DEADLOCK? I mean, imagine a situation below, or
something alike:
{code}
Thread-1: foo1.equals(foo2);
Thread-2: foo2.equals(foo1);
{code}
I guess that with the *right thread interleaving*, it could lead to a deadlock.
I was so amused by this possibility that wrote a dummy snippet to evaluate
this, as you can see here (with appropriate insertion of {{Thread.sleeps}} to
reproduce the desired interleaving):
https://gist.github.com/eribeiro/bd2aca6fbae0255b64ba0b4f896e6a8d
and got some runs to successfully reproduce a deadlock as seen here:
https://gist.github.com/eribeiro/96f95b295a4b90c0d261057d4542063a
Disclaimer: maybe this situation NEVER happens in this particular case (if so,
sorry for disturbing you, *really*), but I thought it was worth mentioning. ;)
I *guess* a possible solution would be to make {{aclIndex}} a {{volatile}}
variable as a "lightweight" alternative to {{synchronized}}, right? Volatile
makes has a happens before semantic and it prevents reordering of statements.
Wdyt?
2. The inherited code has the following snippet (now moved to
{{ReferenceCountedACLCache}}):
{code}
public synchronized Long convertAcls(List<ACL> acls) {
if (acls == null)
return -1L;
{code}
What if the acls list is empty, i.e., {{acls = new ArrayList<>()}}? It's okay
to cache an empty ACL {{List}} or could we just change the lines above to:
{code}
public synchronized Long convertAcls(List<ACL> acls) {
if (acls == null || acls.isEmpty())
return -1L;
{code}
Again, this can NEVER happen in this case above so, I am all for letting it
as-is today. :)
3. The comment in the following snippet seems a bit out of date (list of
longs???):
{code}
/**
* converts the list of acls to a list of longs.
* Increments the reference counter for this ACL.
* @param acls
* @return a list of longs that map to the acls
*/
public synchronized Long convertAcls(List<ACL> acls) {
{code}
4. AtomicLongWithEquals extends AtomicLong. I failed to see a _good_ reason to
create a custom AtomicLong, as its instances are not used as keys. What is the
rationale behind this? Disclaimer: IMO, extending a j.u. library is an
anti-pattern as we don't have control over it and future changes in the parent
class can easily break the codebase.
5. ReferenceCountedACLCache.OPEN_UNSAFE_ACL_ID could be made static besides
being final.
6. ReferenceCountedACLCacheTest#convertACLsNTimes performs n-1 convertions as
seen here (see the ``<`` and the ``-1``):
{code}
for (int i = 0; i < num -1; i++) {
cache.convertAcls(acl);
}
{code}
Is this the intended behaviour?
There are other irrelevant observations, but I will refrain myself from citing
them by now.
Cheers!
Eddie
> ACL cache in DataTree never removes entries
> -------------------------------------------
>
> Key: ZOOKEEPER-2141
> URL: https://issues.apache.org/jira/browse/ZOOKEEPER-2141
> Project: ZooKeeper
> Issue Type: Bug
> Affects Versions: 3.4.6
> Reporter: Karol Dudzinski
> Assignee: Adam Milne-Smith
> Fix For: 3.4.9, 3.5.2
>
> Attachments: ZOOKEEPER-2141-3.4.patch, ZOOKEEPER-2141.patch,
> ZOOKEEPER-2141.patch, ZOOKEEPER-2141.patch, ZOOKEEPER-2141.patch,
> ZOOKEEPER-2141.patch
>
>
> The problem and potential solutions are discussed in
> http://mail-archives.apache.org/mod_mbox/zookeeper-user/201502.mbox/browser
> I will attach a proposed patch in due course.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)