Make CRUDOptions use interface to reduce code duplications#418
Make CRUDOptions use interface to reduce code duplications#418dkasimovskiy merged 11 commits intomasterfrom
Conversation
There was a problem hiding this comment.
Speaking about enum and wrappers.
First of all, it is a breaking change.
The second one is why we use wrapper before enum. It makes code more complicated.
-.withMode(new ModeValue(ModeValue.WRITE))
+.withMode(ModeValue.WRITE)I'm asking you to separate changes on two pull request:
- "Make CRUDOptions use interface to reduce code duplications"
- "Use enum for proxy client parameters"
src/main/java/io/tarantool/driver/api/space/options/crud/enums/CRUDOption.java
Outdated
Show resolved
Hide resolved
src/test/java/io/tarantool/driver/integration/proxy/options/ProxySpaceUpdateOptionsIT.java
Outdated
Show resolved
Hide resolved
akudiyar
left a comment
There was a problem hiding this comment.
Overall: let's not introduce new entities (except enums) if the values do not have any special operations defined on them. IIf there is a strict necessity to do that, let's then
- not make the user write
newevery time (use factory methods likeMyClass.of(value)) - allow the user to use simple (built-in) types where it is possible
Anyway, any such changes are breaking so let's discuss them first. We will need to explain that in a doc and ideally add a memo/page in the wiki to show the users how to fix their code after the update.
Regarding the option names: having CRUD in them is logical, but let's therefore make them easily separable from the rest driver code to eventually make a new library package only for the tarantool/crud support.
...in/java/io/tarantool/driver/api/space/options/crud/contracts/OperationWithFieldsOptions.java
Outdated
Show resolved
Hide resolved
src/main/java/io/tarantool/driver/api/space/options/crud/enums/CRUDOption.java
Outdated
Show resolved
Hide resolved
src/test/java/io/tarantool/driver/integration/proxy/options/ProxySpaceInsertOptionsIT.java
Outdated
Show resolved
Hide resolved
- Remove CRUD<name>Options classes like a duplicates. - Add options directly to the argument list without CRUD<name>Options class builders. - Change Map:toString() test in the ProxyOperationBuildersTest class with EnumMap specific. - Add test in ProxySpaceSelectOptionsIT class with after and first options. Closes #417.
|
I think I was able to get rid of the duplication of the CRUDOptions classes (identical to the ProxyOptions classes) by moving the options directly into the argument list. |
ArtDu
left a comment
There was a problem hiding this comment.
We need to think how these changes modify cluster client working pipeline
| return Optional.ofNullable((T) resultMap.get(option)); | ||
| } | ||
|
|
||
| public Map<String, Object> asMap() { |
There was a problem hiding this comment.
Do we need cope of the map only for prechecking null values? If it's true we can add null checking in addOption method and remove copying
There was a problem hiding this comment.
I think we need an immutable map here
| import io.tarantool.driver.api.SingleValueCallResult; | ||
| import io.tarantool.driver.api.TarantoolCallOperations; | ||
| import io.tarantool.driver.api.space.options.Options; | ||
| import io.tarantool.driver.api.space.options.interfaces.Options; |
There was a problem hiding this comment.
If this change involves user API we need to add it as breaking change in changelog
Needed for #417.
Needed for #417.
Needed for #417.
- Add OperationWith<option-name>Options contract interfaces. - Add ProxyOperationArgument enum class for parts of arguments list. - Change <operation-name>ProxyOperation classes for using with contract interfaces. - Move ProxyOperation interface from `io.tarantool.driver.core.proxy` package to `io.tarantool.driver.core.proxy.interfaces` package. Closes #417.
akudiyar
left a comment
There was a problem hiding this comment.
Almost good, however I don't get why we need to change the package names. Would you mind elaborating a bit about the purpose of the new packages? A lines-and-boxes diagram may be useful
CHANGELOG.md
Outdated
| - Add "mode" option for crud select operation ([#107](https://github.com/tarantool/cartridge-java/issues/107)) | ||
| - Change using of proxy client parameters (mode, rollback_on_error, stop_on_error) with enum classes ([#419](https://github.com/tarantool/cartridge-java/issues/419)) | ||
|
|
||
| - Add `"mode"` option for crud select operation ([#107](https://github.com/tarantool/cartridge-java/issues/107)) |
There was a problem hiding this comment.
Just "select operation" perhaps? Is we are actually making unified API not only for tarantool/crud
There was a problem hiding this comment.
Just "select operation" perhaps? Is we are actually making unified API not only for tarantool/crud
Yeap, we need to separate options between proxy and cluster clients. For example I suggest to make SelectOptions without API extending only Options interface(addOption/getOption and asMap methods) because we use only these methods in inner API. But inheritance interfaces will involve specific methods like mode.
Options (interface)
|
V
SelectOptions (interface)
| |
V V
ProxySelectOptions (interface) ClusterSelectOptions (interface)
| import io.tarantool.driver.api.metadata.TarantoolMetadataOperations; | ||
| import io.tarantool.driver.api.metadata.TarantoolMetadataProvider; | ||
| import io.tarantool.driver.api.space.TarantoolSpaceOperations; | ||
| import io.tarantool.driver.api.space.options.interfaces.TarantoolSpaceOperations; |
There was a problem hiding this comment.
Why do we need to make the packet names longer?
There was a problem hiding this comment.
I wanted a more organized arrangement of interfaces and classes that implement those interfaces. A contract is a contract that interfaces-options expose to classes that implement it.
There was a problem hiding this comment.
All this .api. package is about contracts. Adding more contract sub-layers here seems an overkill
| return Optional.ofNullable((T) resultMap.get(option)); | ||
| } | ||
|
|
||
| public Map<String, Object> asMap() { |
There was a problem hiding this comment.
I think we need an immutable map here
| @@ -1,6 +1,8 @@ | |||
| package io.tarantool.driver.api.space.options; | |||
| package io.tarantool.driver.api.space.options.contracts; | |||
There was a problem hiding this comment.
What does this new package name mean, what does it give to the users?
|
|
||
| return new DeleteProxyOperation<>( | ||
| this.client, this.functionName, arguments, this.argumentsMapper, this.resultMapper); | ||
| this.client, this.functionName, new ArrayList<>(arguments.values()), this.argumentsMapper, |
There was a problem hiding this comment.
Why do we have that additional wrapping here? It will result in significant overhead for memory and GC time at least
There was a problem hiding this comment.
Wrapping in enummap was required to make unification across interfaces possible. If we don't use enummap, how can we connect the parts of the argument list in the correct number and order? After all, for each operation there are parts of the argument list that are different in composition and order.
There was a problem hiding this comment.
I mean the new ArrayList<>() call first of all
There was a problem hiding this comment.
I realize that calling new ArrayList<>() creates intermediate collections. But it seems to me that the same collection is created before, which is later referenced by the "final" argument list:
Either I don't have enough experience to understand the difference between the two cases:
Master case:Commit case:| * | ||
| * @author <a href="https://github.com/nickkkccc">Belonogov Nikolay</a> | ||
| */ | ||
| package io.tarantool.driver.core.proxy.contracts; |
There was a problem hiding this comment.
Do we really need that complex package structure? I haven't seen "contracts" packages in other libraries.
...main/java/io/tarantool/driver/api/space/options/contracts/OperationWIthBatchSizeOptions.java
Outdated
Show resolved
Hide resolved
ArtDu
left a comment
There was a problem hiding this comment.
Good job on improvement our complex API. I wrote some comments. It will be the best if you also create tickets about my notions in java doc
src/main/java/io/tarantool/driver/core/proxy/enums/ProxyOperationArgument.java
Show resolved
Hide resolved
src/main/java/io/tarantool/driver/api/space/options/interfaces/Options.java
Show resolved
Hide resolved
src/main/java/io/tarantool/driver/api/space/options/interfaces/SelectOptions.java
Outdated
Show resolved
Hide resolved
...main/java/io/tarantool/driver/api/space/options/contracts/OperationWIthBatchSizeOptions.java
Outdated
Show resolved
Hide resolved
- Fix `API changes` description. - Fix mistype and typo in `OperationWithBatchSizeOptions` interface. - Add notions to `Options`, `ProxyOperationArgument`, `SelectOptions`. Closes #417.
|
@akudiyar, we decided not to make Map immutable for now. If necessary, we will change it in the next stages. |
akudiyar
left a comment
There was a problem hiding this comment.
Let's not introduce new packages like interfaces and contracts since we are already in the api package that means exactly that. Also think of the amount of changes the users will have to make in their code, will these changes be meaningful?
Also be careful about creating new objects on each call, new ArrayList<> for example is not necessary
akudiyar
left a comment
There was a problem hiding this comment.
See my comment above - let's discuss that verbally if you wish
I haven't forgotten about:
Related issues:
Closes #417