Skip to content
This repository has been archived by the owner on Nov 14, 2024. It is now read-only.

Add new getLockState() debugging endpoint #5302

Merged
merged 6 commits into from
Mar 12, 2021

Conversation

dxiao
Copy link
Contributor

@dxiao dxiao commented Mar 5, 2021

Allows for easier, more targetted debugging than would be
possible with previous logCurrentState() endpoint

Allows for easier, more targetted debugging than would be
possible with previous logCurrentState() endpoint
@dxiao dxiao requested a review from jeremyk-91 March 5, 2021 23:40
@changelog-app
Copy link

changelog-app bot commented Mar 5, 2021

Generate changelog in changelog/@unreleased

Type

  • Feature
  • Improvement
  • Fix
  • Break
  • Deprecation
  • Manual task
  • Migration

Description

Add new getLockState(LockDescriptor) debugging endpoint to the RemoteLockService, which allows for easier, more targeted debugging than would be possible with previous logCurrentState() endpoint. Provide a LockDescriptor, and get the current set of clients holding and waiting for the lock.

Check the box to generate changelog(s)

  • Generate changelog entry

Copy link
Contributor

@sudiksha27 sudiksha27 left a comment

Choose a reason for hiding this comment

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

Given this is a best-effort debugging endpoint, broadly looks okay.
I have a few questions + refactoring suggestions.

@jeremyk-91 would appreciate +2 on this one.

Comment on lines 1173 to 1178
Map<LockRequest, LockClient> requests = new HashMap<>();
outstandingLockRequestMultimap.forEach((client, request) -> {
if (request.getLockDescriptors().contains(descriptor)) {
requests.put(request, client);
}
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Map<LockRequest, LockClient> requests = new HashMap<>();
outstandingLockRequestMultimap.forEach((client, request) -> {
if (request.getLockDescriptors().contains(descriptor)) {
requests.put(request, client);
}
});
Map<LockRequest, LockClient> requests = KeyedStream.stream(outstandingLockRequestMultimap)
.filterEntries((client, request) -> request.getLockDescriptors().contains(descriptor))
.mapEntries((client, request) -> Maps.immutableEntry(request, client))
.collectToMap();

Comment on lines 1168 to 1171
List<HeldLocksToken> heldLocks = new ArrayList<>();
heldLocksTokenMap.keySet().stream()
.filter(token -> token.getLockDescriptors().contains(descriptor))
.forEach(heldLocks::add);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
List<HeldLocksToken> heldLocks = new ArrayList<>();
heldLocksTokenMap.keySet().stream()
.filter(token -> token.getLockDescriptors().contains(descriptor))
.forEach(heldLocks::add);
List<HeldLocksToken> heldLocks = heldLocksTokenMap.keySet().stream()
.filter(token -> token.getLockDescriptors().contains(descriptor))
.collect(Collectors.toList());

.versionId(Optional.ofNullable(request.getVersionId()))
.requestingThread(request.getCreatingThreadName())
.build()));
return lockState.build();
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we can extract util methods for above; these static methods could live in LockState

Copy link
Contributor

Choose a reason for hiding this comment

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

I think factories for creating a LockHolder/LockRequester from the request and/or lock object would be nice, though requests.forEach(...) in the body here seems fine to me

.isWriteLocked(false)
.isFrozen(false)
.build();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Declare a constant?

Comment on lines 1157 to 1166
List<LockClient> lockHolders;
if (readHolders.isEmpty()) {
if (writeHolders == null) {
lockHolders = ImmutableList.of();
} else {
lockHolders = ImmutableList.of(writeHolders);
}
} else {
lockHolders = readHolders;
}
Copy link
Contributor

@sudiksha27 sudiksha27 Mar 9, 2021

Choose a reason for hiding this comment

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

Extract out method, maybe something like -

Suggested change
List<LockClient> lockHolders;
if (readHolders.isEmpty()) {
if (writeHolders == null) {
lockHolders = ImmutableList.of();
} else {
lockHolders = ImmutableList.of(writeHolders);
}
} else {
lockHolders = readHolders;
}
private static List<LockClient> getLockClients(List<LockClient> readHolders, LockClient writeHolders) {
return readHolders.isEmpty()
? Optional.ofNullable(writeHolders).map(ImmutableList::of).orElseGet(ImmutableList::of)
: readHolders;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Seems like a lot of fanciness for not a lot of benefit, but either way's fine by me!

* -The logCurrentState tryLock() call times out after LOG_STATE_DEBUG_LOCK_WAIT_TIME_IN_MILLIS
* and the call moves on to logCurrentStateInconsistent()
*/
barrier.await();
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the comment needs to be modified?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm. On reread, it's not needed at all. removing

@@ -260,7 +260,7 @@ private synchronized void decrementReadCount(int clientIndex) {
}
}

private synchronized Iterable<Integer> getReadClients() {
/* package */ synchronized Iterable<Integer> getReadClients() {
if (readLockHolders == null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: we don't use the "package" comment anywhere else in this class

/* package */ LockServerSync getSync() {
return sync;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: can we remove the package comment for uniformity. Also can we move the package-private method below public methods?

@Override
public LockState getLockState(LockDescriptor lock) {
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

is this right? If so, can we have a comment to explain?

Copy link
Contributor

@jeremyk-91 jeremyk-91 left a comment

Choose a reason for hiding this comment

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

Broadly makes sense, though I'm pretty sure RLSA needs to be different. I think @sudiksha27 had a number of good suggestions.


@Override
public LockState getLockState(LockDescriptor lock) {
return null;
Copy link
Contributor

Choose a reason for hiding this comment

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

surely namespaceAgnosticLockRpcClient.getLockState(lock);?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oops!

.versionId(Optional.ofNullable(request.getVersionId()))
.requestingThread(request.getCreatingThreadName())
.build()));
return lockState.build();
Copy link
Contributor

Choose a reason for hiding this comment

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

I think factories for creating a LockHolder/LockRequester from the request and/or lock object would be nice, though requests.forEach(...) in the body here seems fine to me

@dxiao
Copy link
Contributor Author

dxiao commented Mar 12, 2021

Updated! Let me know if there's anything else to do. Otherwise, would live to get this in time for the weekly release :)

Copy link
Contributor

@jeremyk-91 jeremyk-91 left a comment

Choose a reason for hiding this comment

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

👍 let's merge this!

@bulldozer-bot bulldozer-bot bot merged commit c5fd8d1 into develop Mar 12, 2021
@bulldozer-bot bulldozer-bot bot deleted the features/get-lock-state branch March 12, 2021 17:47
@svc-autorelease
Copy link
Collaborator

Released 0.307.2

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants