Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid acquiring closeLock.readLock() on every add/read operation #1292

Closed
wants to merge 2 commits into from

Conversation

merlimat
Copy link
Contributor

In the BookieClient, we are always acquiring a readlock when grabbing a connection to use for sending a write/read request.

The lock is the closeLock and it's only acquired in "write" mode when the BookKeeper instance is closed.

The problem with the read-lock is that it introduces contention between the threads that are acquiring it (even if all of them in read mode). Multiple threads can be be in read mode in the critical section, though they have contention when they're entering/exiting the section.

Additionally, the Java implementation of read/write lock is creating and destroying a lot of objects when that contention happens.

My understanding of the code is that we don't need to acquire the read lock in that point. The reason is that, we are already acquiring the lock in the lookupClient() method, although only if the pool is null. Additionally, when Bookkeeper.close() is invoked all PCBC will be set to closed as well, so it will not be possibile to create a new connection.

All the line changes in the patch are just removing the readLock acquire and try/finally, and reducing the indentation level.

@merlimat merlimat added this to the 4.7.0 milestone Mar 24, 2018
@merlimat merlimat self-assigned this Mar 24, 2018
Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 sounds good to me

@sijie
Copy link
Member

sijie commented Mar 24, 2018

I am not sure that is right. If I remembered correctly, the lock is prevent client try to obtain a connect when closing. I think the reason you don't want contention in this level, because it is shared across all pcbc tools. you might consider pushing one level or two levels down.

However if my understanding is wrong, you might also want to remove the read write lock variable, since we don't really need a rw lock after your change.

@merlimat
Copy link
Contributor Author

If I remembered correctly, the lock is prevent client try to obtain a connect when closing.

Yes, though I think we should be able to do :

  • Mark client as "closed" - no new connections will be attempted
  • Close all active connections

This should not require the RW lock

However if my understanding is wrong, you might also want to remove the read write lock variable, since we don't really need a rw lock after your change.

There is still the check when creating the PCBC pool. So it will check for it before creating a new connection, but not each time when using an existing connection.

@sijie
Copy link
Member

sijie commented Mar 24, 2018

Mark client as "closed" - no new connections will be attempted
Close all active connections

Is that in current PR?

@sijie
Copy link
Member

sijie commented Mar 24, 2018

retest this please

Copy link
Member

@jiazhai jiazhai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Contributor

@ivankelly ivankelly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm.

As I understand it, the read write lock should just prevent new pools from being added after close is called. The pools themselves don't need a lock, and pcbc is already full of locks.

Some minor nits, but feel free to ignore.

}
pcbc.readLac(ledgerId, cb, ctx);
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the return is actually to avoid the pcbc.readLac(ledgerId, cb, ctx); but it would be clearer with an else block anyway.

} else {
pcbc.writeLac(ledgerId, masterKey, lac, toSend, cb, ctx);
toSend.retain();
client.obtain(new GenericCallback<PerChannelBookieClient>() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: these can become lambdas

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sense, I didn't do it initially since I just removed try/finally and de-indented, but since it anyway looks like these lines are changed.. I might as well convert them.

Copy link
Member

@sijie sijie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@merlimat can you rebased to latest master? so it includes #1287 fix for CI.

@merlimat
Copy link
Contributor Author

Rebased and addressed comments

@merlimat merlimat closed this in 9df8dac Mar 29, 2018
@merlimat merlimat deleted the bookie-client-rw-lock branch March 29, 2018 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants