Repository navigation
DAO module clean up and refactoring - #706
softqwewasd merged 7 commits into
Conversation
|
And just to confirm that we're on the same page here this PR does not add support for execution of arbitrary SQL text unless you implement the full Statement interface etc, right? |
|
Suggestion: reword from "Slow query:" to "Slow execution"; most often it's not the database that's slow, it's the thread being starved due to garbage collection. |
Yes 👍 |
|
I would really like to see a much higher grade of code coverage here. Regardless of coverage of the old code, it was battle tested and known to work. If we are to make these changes and feel confident that it works, good coverage of tests is key. Most of the coverage from Edit: I did not notice that ReactiveStatementFactoryTest was renamed to DaoMethodHandlerTest. This just means that DaoMethodHandlerTest is poorly covered and ReactiveStatementFactory doesn't have a single unit test. |
| this.metrics = metrics; | ||
| } | ||
|
|
||
| public Publisher<Object> run(Object[] args, ReactiveStatementFactory reactiveStatementFactory) { |
There was a problem hiding this comment.
Naming here is slightly ambiguous since we are not actually running the handler, we are creating a handler?
|
Have you checked that these changes work with the internal RW? Is there a branch in the internal RW that we can view? |
niklasga
left a comment
There was a problem hiding this comment.
I cannot say much about the functionality of the dao module, but I have a few concerns quality wise. Hopefully it should not be too painful to get some decent code coverage and add javadocs :)
| public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { | ||
| ReactiveStatementFactory reactiveStatementFactory = statementFactories.get(method); | ||
| if (reactiveStatementFactory == null || DebugUtil.IS_DEBUG) { | ||
| var handler = handlers.get(method); |
There was a problem hiding this comment.
Please use actual types instead of var, especially when it's not easily inferred from the code.
|
|
||
| import java.lang.reflect.Method; | ||
|
|
||
| public class DaoMethodHandler { |
There was a problem hiding this comment.
Add javadocs to explain the purpose of the class and at least the public methods on it.
You had some good explanations of classes and concepts in your PR description, those would be nice to transfer to well placed comments for future reference :)
| Mono<T> resultMono = getResultMono(statementContext); | ||
| if (shouldAddDebugErrorHandling()) { | ||
| resultMono = resultMono.onErrorResume(thrown -> | ||
| Mono.error(new RuntimeException(QUERY_FAILED, thrown)) |
There was a problem hiding this comment.
Will this not result in creating new RuntimeExceptions for each error, as opposed as the old code reusing the same one?
There was a problem hiding this comment.
Will this not result in creating new RuntimeExceptions for each error, as opposed as the old code reusing the same one?
In the old code, each time method ReactiveStatementFactory#create is called, the new instance of exception is created.
The only difference is that now exception is created only if error happens while previously it was created even if error didn't happened.
The reusability of the exception instance could only happen in the old code if lambda provided to method onErrorResume is called several times. I suppose this may happen if we add a retry. Is there any benefit in reusing the exception instance in this case?
| resultFlux = Flux.from(metrics.measure(resultFlux, this::logSlowQuery)); | ||
| resultFlux = resultFlux.onBackpressureBuffer(RECORD_BUFFER_SIZE); | ||
| return decorated(resultConverter.apply(resultFlux), statementContext); | ||
| public <T> Mono<T> createMono( |
There was a problem hiding this comment.
The old create method actually had javadocs that you removed, would you please add them to your new create-methods?
|
Have you checked if any other dependents other than internal RW are impacted by these changes? |
Yes. I have created a branch |
No, but I don't see an issue if others are dependent too. They would need to update the constructor usages as was done in internal RW. |
I have renamed |
e072215 to
5d91e1e
Compare
|
I have added javadocs and more tests. |
|
I looked through the pr and i just have some general thoughts that I do not think you need to resolve now to get the pr merged.
Then the proxy class would look something like this:
But overall it looks nice, hope it works well for you :) |
|
@splitfeed Can you review again? |



1. Remove resultConverter from ReactiveStatementFactory
ReactiveStatementFactoryalways createsMonoif dao method return type isMonoandFluxif return type isFlux. So it looks like there is no need for a converter.The check that return type is Mono or Flux was moved to
ReactiveStatementFactory.2. Remove paramSerializer from DbProxy
There are no usages of
paramSerializerfield inDbProxy. I have checked internal RW too. So it looks like it is safe to remove it.3. Move dao method related code from ReactiveStatementFactory to DaoMethodHandler
Currently
DbProxyhas two "roles":And
ReactiveStatementFactoryhas two "roles":My idea is to distribute "roles" in the following way:
So this refactoring has moved the following code:
ReactiveStatementFactoryto a new classDaoMethodHandlerDbProxytoReactiveStatementFactoryNote: previously if query execution was slow then the query sql was logged, now the metric name related to the dao method will be logged instead.
We did this change so that we don't need to pass sql text as a parameter.
And it will be easier for a developer to find this query in the code.
So previously log message may look like this:
Now it may look like this: