-
Notifications
You must be signed in to change notification settings - Fork 445
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
IteratorEnvironment
fixes
#4816
base: 2.1
Are you sure you want to change the base?
Conversation
closes apache#4810 - Fixed some inconsistencies and bugs in (non-test) implementations of `IteratorEnvironment` - Fixed `RFileScanner`s unexpected `UnsupportedOperationException` when calling `env.getServiceEnv()` or `env.getConfig()` (both deprecated) or `env.getPluginEnv()` - Changed the impls to return the same object for calls to `getServiceEnv()`/`getPluginEnv()` (expected by `IteratorEnvIT`) - Fixed inconsistencies in functionality of `isUserCompaction()` and `isFullMajorCompaction()` when it is not a major compaction. Added missing javadoc to `isUserCompaction()` - Added tests for these environments to `IteratorEnvIT`
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.
Still looking at this, posting comments I have so far. Will circle back to this later.
core/src/main/java/org/apache/accumulo/core/client/rfile/RFileScanner.java
Show resolved
Hide resolved
core/src/main/java/org/apache/accumulo/core/client/rfile/RFileScanner.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/apache/accumulo/core/client/rfile/RFileScanner.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/apache/accumulo/core/client/rfile/RFileScanner.java
Show resolved
Hide resolved
- Updated RFile javadocs - Added description of new supported functionality for `RFile.ScannerOptions.withTableProperties()` - Moved `@see` tag in javadoc for `RFile.{ScannerOptions/SummaryOptions}.withTableProperties(Map<String,String>)` which was incorrect - Changed `RFileScanner.IterEnv.getTableId()` to return a dummy table id to be used for calling `RFileScanner.IterEnv.getConfiguration(TableId)` - Added functionality for `RFileScanner.IterEnv.instantiate()` - Added error msg to invalid uses of `RFileScanner.IterEnv.getServiceEnv()/getPluginEnv()` methods
core/src/main/java/org/apache/accumulo/core/client/rfile/RFileScanner.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/apache/accumulo/core/client/rfile/RFileScanner.java
Show resolved
Hide resolved
- Minor RFileScanner changes - Refactored IteratorEnvIT to ensure expected assertions are executed
* True if compaction was user initiated. Will throw IllegalStateException if | ||
* {@link #getIteratorScope()} != {@link IteratorScope#majc}. |
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.
* True if compaction was user initiated. Will throw IllegalStateException if | |
* {@link #getIteratorScope()} != {@link IteratorScope#majc}. | |
* @return True if compaction was user initiated, false otherwise. | |
* @throws IllegalStateException if {@link #getIteratorScope()} != {@link IteratorScope#majc} |
* <p> | ||
* Starting with {@code 2.1.4}, {@link PluginEnvironment#getConfiguration(TableId)} (obtained by | ||
* {@link IteratorEnvironment#getPluginEnv()}) will return the properties passed in here. | ||
* |
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.
I'm not sure these comments about "starting with 2.1.4" make sense to include here. It should have always worked this way. This is just fixing a bug. I don't think we need to document the implementation details of the corrected behavior for the bug fix in the javadoc.
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.
Okay, I will remove this in my next commit. Should I just remove the mention of 2.1.4
or that new part entirely?
var ctx = context.get(); | ||
try { | ||
return new ConfigurationCopy( | ||
ctx.tableOperations().getConfiguration(ctx.getTableName(tableId.get()))); | ||
} catch (AccumuloException | TableNotFoundException e) { | ||
throw new RuntimeException("Error getting table configuration", e); | ||
} |
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.
What is the rationale for implementing getConfig
, and specifically as a copy of the table configuration? The behavior of this method in the interface was never well-defined, and was using an internal API and should never be called by user code. I'm not sure why it needs an implementation here, rather than just throwing an exception, like the deprecated default method does in the interface.
If we really do need this, the default method in the interface should implement it by calling the methods on getPluginEnv()
and wrapping it similarly to what you did here, instead of that default method throwing an exception.
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.
I implemented it here since I thought that because it was deprecated but not yet removed, there should still be functionality for the method. The other impls of IteratorEnvironment
still have this implemented; assumed same should be the case here. Less importantly, this also made testing the different impls of IteratorEnvironment
in IteratorEnvIT
more straight forward as each would call getConfig()
, getServiceEnv()
, and getPluginEnv()
. If this shouldn't be implemented here, I can remove it, or I could change the default impl to use getPluginEnv()
like you said. Whichever you think would be better.
public PluginEnvironment getPluginEnv() { | ||
return new ClientServiceEnvironmentImpl(context.get()); |
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.
This is the method that should be implemented. The getServiceEnv()
method only existed for backwards compatibility. The code should not rely on the interface implementation of getPluginEnv()
calling the getServiceEnv()
here, because that behavior is removed when the deprecated code is dropped. Instead, it's best to keep both methods, as before your change, so that when the deprecated one is dropped in subsequent versions, the correct implementation is kept.
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.
Thanks, this was something I was unsure about when implementing this. Some IteratorEnvironment
s had both getServiceEnv()
and getPluginEnv()
(e.g., OfflineIterator
) while some had just getServiceEnv()
(e.g., TabletIteratorEnvironment
), and I wasn't sure which to go with. I'll fix the impls to use both.
private static final String errorMsg = | ||
"This scanner is unrelated to any table or accumulo instance;" | ||
+ " it operates directly on files. Therefore, it can not support this operation."; | ||
private static final TableId dummyTableId = TableId.of("RFileScannerFakeTableId"); |
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.
Why wouldn't this be null?
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.
Discussed here: #4816 (comment). Either null or a dummy would work though.
@@ -311,14 +319,27 @@ public void updateScanIteratorOption(String iteratorName, String key, String val | |||
} | |||
|
|||
private class IterEnv implements IteratorEnvironment { | |||
private final Supplier<ServiceEnvironment> serviceEnvironment; |
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.
What prevents us from just using the implementation from super.getPluginEnv()
and super.getServiceEnv()
?
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.
IteratorEnvironment
doesn't have any implementation for getServiceEnv()
or getPluginEnv()
. Or are you suggesting changing IteratorEnvironment
?
* @return true if the compaction is a full major compaction; false otherwise | ||
* @throws IllegalStateException if {@link #getIteratorScope()} != {@link IteratorScope#majc}. |
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.
I think I would have preferred fixing the documentation to drop the exception case, rather than forcing an exception to be thrown in all the scan cases. false otherwise
should be sufficient. Have you considered that as an alternative?
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.
I hadn't looked into why an exception was thrown, I had just kept the functionality the same and consistent across impls. I assumed there was probably a reason for wanting all impls to throw an exception and didn't look any further.
Are you suggesting to drop the documentation about the exception case and revert the changes I made to adhere to the exception case, or are you suggesting changing the functionality to no longer throw the exception, or something else?
After a conversation with @kevinrr888, I added commit 5924b02 to incorporate some of the changes we discussed, that he intends to build on and polish up. The main points included were:
The main thing left unresolved after our conversation was how to fix the mismatch between the implementations and the javadoc for all the methods that inconsistently return null or throw IllegalStateException or UnsupportedOperationException, when calling a method that doesn't apply to a given situation (like asking for a table ID or table name when operating directly on RFiles or asking if it's a user-initiated compaction when it's a scan). Nearly every caller seems to have a unique set a requirements/implementation, and it's a bit hard to home in on the best implementation, especially for the default methods, and make sure the javadoc matches the behavior. |
- Changed ClientSideIteratorScanner.getConfig() to use the safer getPluginEnv() - Added getPluginEnv() impl to all IteratorEnvironments (besides test envs) - Improved RFile.ScannerOptions.withTableProperties() javadoc to better explain how iterators will have access to these properties - Opted for RFileScanner.IterEnv.getTableId() to return null instead of a dummy id - Removed incorrect impl of RFileScanner.IterEnv.get(Service/Plugin)Env().getTableName() to instead just throw UnsupOpExc since the method doesn't make sense anyways. Co-authored-by: Christopher Tubbs <[email protected]>
5924b02
to
a68ec11
Compare
Some comments about decisions in a68ec11 Comment about
|
closes #4810
IteratorEnvironment
RFileScanner
s unexpectedUnsupportedOperationException
when callingenv.getServiceEnv()
orenv.getConfig()
(both deprecated) orenv.getPluginEnv()
ServiceEnvironment
for each call togetServiceEnv()
/getPluginEnv()
. This did not align as well with theIteratorEnvIT
which would assert that these two calls return the same object. Memoize a supplier to theServiceEnvironment
to avoid creating the object unless needed and to return the same object each time.isUserCompaction()
andisFullMajorCompaction()
are supposed to be throwing anIllegalStateException
if it's not a major compaction. Added missing javadoc toisUserCompaction()
and changed impls that were not adhering to these docs.IteratorEnvIT
Questions:
RFileScanner
. Is this correct? ANSWEREDgetConfiguration()
throw an error inRFileScanner
sIteratorEnvironment
since I'm not sure how we would return the system config in this context and I don't think it would even make sense here. Does this seem right? ANSWEREDIteratorEnvironment
forRFileScanner
return null and not throw an error onenv.getTableId()
so something like:env.getPluginEnv().getConfiguration(env.getTableId())
can be done. Thoughts on this? ANSWERED