-
Notifications
You must be signed in to change notification settings - Fork 274
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
GetManager implementation with GetBlobInfo support #276
Conversation
@@ -131,4 +131,19 @@ public String toString() { | |||
sb.append("]"); | |||
return sb.toString(); | |||
} | |||
|
|||
@Override |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you write equals()
, don't you need to write hashCode()
too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We haven't really been following that practice elsewhere in our codebase, but yes that is recommended practice. However, on second thought, I feel more comfortable not overriding equals() in the first place (MessageFormat actually returns the BlobProperties via a private SystemMetadata class that overrides BlobProperties and equals() below ignores the class equality). Will move this check into the test itself.
Done with production code. Going to take a look at test code late today or tomorrow. |
// Because there is a guaranteed response from the NetworkClient for every request sent out, entries | ||
// get cleaned up periodically. | ||
private final Map<Integer, GetOperation> correlationIdToGetOperation = new HashMap<Integer, GetOperation>(); | ||
private final AtomicBoolean isOpen = new AtomicBoolean(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isOpen unused ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed.
} | ||
|
||
/** | ||
* Tests the failure case where poll throws and closes the router. This also tests the case where the GetManager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doc says, also tests the case where the GetManager is closed. Where exactly do you check that the getManager is closed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests the case where the GetManager
gets closed, not that it is closed specifically. Basically, ensures that the GetManager#close()
is called and completes existing operations with the RouterClosed
error, by checking exactly that.
Updated to address all review comments so far, please take a look. |
NonBlockingRouter.completeOperation(op.getFuture(), op.getCallback(), null, | ||
new RouterException("Aborted operation because Router is closed", RouterErrorCode.RouterClosed)); | ||
for (PutOperation op : putOperations) { | ||
// There is a rare scenario where the operation gets removed from this set and gets completed concurrently by |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How did you figure this out(duplicate completion). Some tests which does parallel puts ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No - just from my understanding and analysis of the code. It is hard to reproduce this through any tests.
Looks good |
|
||
/** | ||
* Set the exception associated with this operation. | ||
* A {@link ServerErrorCode#Blob_Deleted} or {@link ServerErrorCode#Blob_Expired} error overrides any other |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you might want to have a predictable order b/w expired and deleted blob to provide a consistent experience when the GET APIs are used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, but I think that is already being handled to the extent it can be. The chances of a blob being expired in some replicas and deleted in certain others is very slim, but even if that happens, here we ensure that the first such error that is reported is returned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed that the chances are slim, but for a short period of time, one call might return expired, and another deleted depending on a lot of factors.
It's not a big problem so we can add it to the backlog when we eventually have to handle precedence among all router error codes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point is that there is no way to handle this. It depends completely on the order in which replicas are contacted (which changes between calls). Not unless we continue to handle responses in case of Deleted/Expired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And even if they are contacted in the same order, there is no guarantee on the order of the responses.
LGTM. Few minor comments - can merge once addressed |
* An abstract class for a get operation. | ||
* @param <T> the type of the result of this operation. | ||
*/ | ||
abstract class GetOperation<T> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I missed your point. Why you make GetOperation
abstract?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two types of GetOperation
s - GetBlobInfoOperation
and GetBlobOperation
.
Addressed all comments. |
97a7c94
to
e499475
Compare
LGTM. Merging this but please follow up on any unresolved comments by @xiahome. |
Also, I assume you have built and formatted. |
LGTM. |
This PR adds the initial GetManager implementation with support for
getBlobInfo()
operations, with associated unit tests.This PR also includes a few fixes here and there within the PutManager and the mock classes, which are mostly minor. The most relevant of these changes is within the MockServer in the way it constructs the responses. With the changes, it reuses the functionalities from the production code rather than construct responses manually.
Because the changes for
getBlob()
support were part of this change and later removed from this PR in order to help simplify the reviews, there may be a few things that might seem unnecessary if you look at this patch in isolation (for example, one might wonder why certain methods are (or are not) in the abstractGetOperation
class), so do keep in mind that those might be to supportgetBlob()
(that will be put up as a PR once this gets merged).Primary reviewers:
Siva, Gopal
Coverage