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
GH-1387 Improved custom service executor extension system #1388
Conversation
return null; | ||
} | ||
|
||
protected QueryIterator nextStage(QueryIterator input) { |
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.
Please explain what is going on here.
If a change is needed, then having a superclass is not necessary. Just two nextStage
methods with different signatures.
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.
QueryIterApplyBulk's nextStage(QueryIterator)
method flat-maps the input QueryIterator
to an output QueryIterator
until the input iterator is consumed - i.e. implementations of nextStage can "per stage" consume an arbitrary amount > 0 from the input iterator.
QueryIterApply implements QueryIterApplyBulk.nextStage(QueryIterator)
such that it delegates to its own usual QueryIterApply.nextStage(Binding)
method.
In other words, QueryIterApplyBulk
is all methods of QueryIterApply
minus this one delegate.
Note that QueryIterApplyBulk
is also the base class for QueryIterServiceBulk
. The latter only operates on the QueryIterator
and therefore does not need a nextStage(Binding)
method. I find this separation cleaner than having both nextStage
methods on the same class together with an override that causes the binding-level one to no longer be called. Other than that, having both methods on the same class would work too.
The only drawback I see with this separation is that reflection code that relied on QueryIterApply.class.getDeclaredMethods()
would break.
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 find this separation cleaner
My concern is that this is making the bulk case "normal" when in fact it is special to your service work.
jena-arq/src/main/java/org/apache/jena/sparql/ARQConstants.java
Outdated
Show resolved
Hide resolved
Just to clarify, my next step on this PR is to update and write javadoc; especially for what purpose some of the classes are for. This should make reviewing easier. |
jena-arq/src/main/java/org/apache/jena/sparql/engine/iterator/QueryIterRepeatApply.java
Outdated
Show resolved
Hide resolved
May latest attempt at cleaning up and simplifying things:
If there should be a dedicated QueryIterService which calls the registry rather than OpExecutor doing that, then actually the proper base class would be something like a QueryIterDeferred / LazyInitialization: That iterator just takes the iterator returned by the service handler and serves from it. No repeat apply / batching / stages needed at that time. |
|
||
/** Root of query iterators in ARQ. */ | ||
|
||
public interface QueryIterator extends Closeable, Iterator<Binding>, PrintSerializable | ||
public interface QueryIterator extends ClosableIterator<Binding>, PrintSerializable |
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 change isn't necessary but if it is made, please use IteratorCloseable
See the comments in ClosableIterator which refer to the Model API and ExtendedIterator
- let's keep ClosableIterator
for jena-core.
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.
Updated. It seemed reasonable to add one of the interfaces that already combined iterator with close - it was a 50/50 chance 😄
@@ -32,8 +32,8 @@ | |||
import org.apache.jena.sparql.engine.main.QC ; | |||
import org.apache.jena.sparql.exec.http.Service; | |||
import org.apache.jena.sparql.service.ServiceExecution; |
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 now an unused import and can be removed.
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 removed the import and added a deprecation annotation because QueryIterService is now no longer used but existing code may have sub-classed from it.
Looks good - 2 small comments. Then it's the checklist items : javadoc item and how you want to commits to look when merged to the codebase. e.g any squashing and and any use of "GH-1387: " to pick out key commits. |
I noticed that the overloaded
I updated javadoc and added a couple of |
Squashed |
Are there any documentation changes for Also - 2 or 3 sentences for the 4.6.0 release announcement would be good. |
GitHub issue resolved #1387.
This fixes #1399.
Pull request Description: This PR adds the following changes to the custom service executor plugin system:
Improvements:
ChainingServiceExecutor
which allows for transparently forwarding a request to the nextChainingServiceExecutor
instance in the registry. This way a custom service executor can modify the request and have it processed by the remainder of the chain.createExecution
method accepts a singleBinding
or aQueryIterator
. There is now aServiceExecutorRegistryBulk
which by default has an registration that delegates to the non-bulk one.Breaking changes:
ServiceExecutorRegistry.getFactories()
now returns aList<ChainingServiceExecutor>
because this is its internal storage; previously it wasList<ServiceExecutorFactory>
. I am afraid re-establishing compatibility in this regard would require a completely new registry with a new context attribute.Deprecations:
ServiceExecutorFactory
in favor ofServiceExecutor
(ServiceExecutorFactory extends from the latter). Use of the old code delegates to the new one.ServiceExecution
is now calledcreateExecution
(rather thancreateExecutor
)DeprecatedQueryEngineFactory also usesServiceExecutorRegistry.add
in favor ofprepend
. Both methods add executors to the beginning of the registry's list so they are considered before the default behavior.add
to prepend; soadd
is consistent with existing naming.ServiceExecutorFactory
exists and wraps it as aChainingServiceExecutor
.ServiceExecutorFactory
finds previously wrapped elements..ServiceExecution
because it doesn't add anything overQueryIterator
.By submitting this pull request, I acknowledge that I am making a contribution to the Apache Software Foundation under the terms and conditions of the Contributor's Agreement.
See the Apache Jena "Contributing" guide.