Skip to content
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

ISPN-10322 Create unified interface for initializing commands #6834

Merged
merged 4 commits into from Jun 21, 2019

Conversation

ryanemerson
Copy link
Contributor

@ryanemerson ryanemerson commented Apr 4, 2019

@danberindei @wburns This is an attempt to standardise the way in which we initialise our RPC commands to remove the need for the switch statement in CommandsFactoryImpl. This started when I was bored at the airport, so feel free to tear it apart 😄.

In order to avoid creating a sub-interface, e.g. ComandInitialisationContext, the InitializableCommand#init method takes in the ComponentRegistry and I have cached the components required throughout core to avoid hash lookups. The Expose* commits, was just a logical way of exposing sub-components by managers in order to reduce the amount directly expose by the ComponentRegistry. I'm not sure whether this is a good/bad idea.

I have left support for ModuleCommandInitializer as this can be more powerful e.g. hibernate CacheCommandInitializer. However, if we go with this approach we should probably all ModuleCommandExtensions#getModuleCommandInitializer to return null or provide a default impl that does this.

I've only update the core module for now, if this is something to pursue then I will update the other modules that utilise ModuleCommandInitializer.

https://issues.jboss.org/browse/ISPN-10322

Copy link
Member

@galderz galderz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Just a minor comment about the function instance variable.

@ryanemerson
Copy link
Contributor Author

There's still a lot of failures on this branch, but I don't want to waste time resolving them until the general idea is approved. If not, I'll just close the PR.

@tristantarrant
Copy link
Member

Overall I like this approach a lot.

@wburns
Copy link
Member

wburns commented Jun 5, 2019

Overall I like the approach as well as it keeps the code cleaner. I would love to see the perf difference; I am guessing it is negligible though (since it is a megamorphic call now instead but doesn't have the switch statement).

@ryanemerson ryanemerson force-pushed the init_commands_2 branch 4 times, most recently from 16e9829 to e1cdfda Compare June 18, 2019 10:38
@ryanemerson ryanemerson force-pushed the init_commands_2 branch 2 times, most recently from bad32e1 to bb9c7d8 Compare June 18, 2019 15:30
@ryanemerson ryanemerson changed the title Initializable Commands ISPN-10322 Create unified interface for initializing commands Jun 18, 2019
@ryanemerson
Copy link
Contributor Author

Updated to apply the approach to all of our modules. @danberindei please take a look when you get a chance as I'm sure you'll be more interested then most.

@ryanemerson ryanemerson added this to the 10.0.0.Beta4 milestone Jun 18, 2019
@ryanemerson
Copy link
Contributor Author

run performance tests please

@ghost
Copy link

ghost commented Jun 18, 2019

Performance tests didn't finish successfully. @diegolovison, can you review it?

Additional info:
Commit: 23f63db
Build number: #345
Comment body: run performance tests please
skip ci

@diegolovison
Copy link
Contributor

@ryanemerson blocked by radargun/radargun#603

@diegolovison
Copy link
Contributor

run performance tests please

@ghost
Copy link

ghost commented Jun 19, 2019

Performance tests run successfully. Link to the results here.

Additional info:
Commit: 23f63db
Build number: #346
Comment body: run performance tests please
skip ci

@danberindei
Copy link
Member

@ryanemerson I would say it's a step in the right direction, but it doesn't go far enough!

I would like to get rid of the separate remote initialization step completely and instead add a method CacheRpcCommand.invoke(ComponentRegistry). We don't need the isRemote flag because we already have getOrigin() != null.

For local invocation, the invoker already knows the concrete type, so instead of adding a LocalInvocation layer it should call a concrete method that doesn't need the entire component registry and response unwrapping. Besides, LocalInvocation is blocking, so it should go away anyway. But I think this can be done in a separate PR.

Currently global commands use wireDependencies(), I'd like to get rid of that in the near future and create a GlobalRpcCommand interface with an invoke(GlobalComponentRegistry) method.

Further out, I hope to replace the interface invoke with an annotation, so commands can declare the components they need as parameters, and generated code takes care of both injection and caching, then I can finally retire ComponentRegistry :) It will require one hash map lookup to get the accessor, but I think it's worth it.

Copy link
Member

@danberindei danberindei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, forgot to press submit

@@ -156,17 +155,12 @@ private void prepareForValidation() {
// Besides, any cache interceptor initialization should only be done once.
// Synchronizes on the cache instance since it's shared between regions with same name.
synchronized (cache) {
PutFromLoadValidator found = findValidator(cache);
PutFromLoadValidator found = cache.getComponentRegistry().getComponent(PutFromLoadValidator.class);
validator = found != null ? found : new PutFromLoadValidator(cache, factory, factory.getPendingPutsCacheConfiguration());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems wrong, either the PutFromLoadValidator is supposed to be registered in the component registry and shared with others using the same cache, or it's not supposed to be registered and we should just create an instance here.

public void init(ComponentRegistry componentRegistry, boolean isRemote) {
Cache cache = componentRegistry.getCache().wired();
searchFactory = ComponentRegistryUtils.getSearchIntegrator(cache);
queryInterceptor = ComponentRegistryUtils.getQueryInterceptor(cache);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I don't like about having an interface: ComponentRegistry can only cache core components, so other modules have to go back to hash map lookups. The effect on performance may be close to nil, but still it's annoying.

this.invoker = componentRegistry.getInterceptorChain().running();
this.icf = componentRegistry.getInvocationContextFactory().running();
this.txTable = componentRegistry.getTransactionTableRef().running();
markTransactionAsRemote(isRemote);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only place where we need the isRemote parameter. I'd rather remove the remote flag from GlobalTransaction, TBH it always bugged me that the identifier of a transaction is different depending on who you're asking.

@Override
public ModuleCommandInitializer getModuleCommandInitializer() {
return new ModuleCommandInitializer() {
@Inject EmbeddedCacheManager cacheManager;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you're removing implementations from other modules I'd rather extend the test implementation here to add a custom command and verify that it keeps working.

@danberindei danberindei merged commit eb3386a into infinispan:master Jun 21, 2019
@danberindei
Copy link
Member

Integrated, thanks Ryan!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants