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

Infinispan Embedded Extension #3832

Merged
merged 6 commits into from
Oct 11, 2019
Merged

Conversation

wburns
Copy link
Member

@wburns wburns commented Sep 3, 2019

Adds in initial support to get Infinispan Embedded working as an extension in Quarkus when running in native mode.

This PR only includes Infinispan core and thus querying is not yet included.

@wburns wburns added the area/infinispan Infinispan label Sep 3, 2019
@FroMage
Copy link
Member

FroMage commented Sep 4, 2019

@Sanne would you be able to review this?

@machi1990
Copy link
Member

Fixes #3617

@Sanne Sanne self-assigned this Oct 7, 2019
@Sanne
Copy link
Member

Sanne commented Oct 7, 2019

hey @wburns - sorry it took so long, it's failing now if I try a rebase. I guess something changed in the meantime:

[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:0.10.0:build (default) on project quarkus-integration-test-infinispan-embedded: Failed to build a runnable JAR: Failed to build a runner jar: Failed to augment application classes: Build failure: Build failed due to errors
[ERROR] 	[error]: Build step io.quarkus.deployment.steps.ConfigurationSetup#initializeConfiguration threw an exception: java.lang.IllegalArgumentException: No Converter registered for class class io.quarkus.runtime.configuration.MemorySize

Copy link
Member

@Sanne Sanne left a comment

Choose a reason for hiding this comment

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

Looks pretty good, although it doesn't take advantage of many more optimisations we could do. I wonder if you have plans for later, or if I'm missing something about the use case.

Some changes are necessary though at least to make it work - see my PR comment #3832 (comment)

(and since it didn't build for me I couldn't actually try it out in native yet)

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2019 Red Hat, Inc.
Copy link
Member

Choose a reason for hiding this comment

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

You might want to skip the copyright headers.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh nice, didn't know we can get rid of them now :)

import io.quarkus.infinispan.embedded.runtime.InfinispanRecorder;

class InfinispanEmbeddedProcessor {
@BuildStep
Copy link
Member

Choose a reason for hiding this comment

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

Just wondering, why do we need to index all these components?

Are we unable to "pre-start" the internal registries and metadata - wouldn't that make this unnecessary?

Copy link
Member Author

Choose a reason for hiding this comment

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

The extension will need to be able to read in a configuration file at runtime, thus we need to be able to have all the required classes available via reflection. JGroups has every protocol (50+) and property required for reflection. Infinispan needs to have quite a few classes as well. The reason then for using the index, is so I don't have to hard code every single one of these classes in the extension, which would be prone to breakage, especially as we don't control JGroups.

void allowReflectionForTransactions(Capabilities capabilities, BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
if (capabilities.isCapabilityPresent(Capabilities.TRANSACTIONS)) {
// Our JBossStandaloneJTAManagerLookup uses reflection on these
reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, "com.arjuna.ats.jta.TransactionManager"));
Copy link
Member

Choose a reason for hiding this comment

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

you could make these unnecessary, just include a TXM lookup implementation which depends on the module?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure I understand sorry. I didn't see any module that registers this via reflection. Although the more I look at it I can just use a substrate substitution instead of this.

ServiceLoader<?> serviceLoader = ServiceLoader.load(serviceLoadedInterface);
List<String> interfaceImplementations = new ArrayList<>();
serviceLoader.forEach(mmb -> interfaceImplementations.add(mmb.getClass().getName()));
if (!interfaceImplementations.isEmpty()) {
Copy link
Member

Choose a reason for hiding this comment

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

Ok this makes me a bit sad :-/ Can't you prepare the bootstrap of the EmbeddedCacheManager upfront?

Such operations like looking up components shouldn't belong in the "runtime phase".

Of course my comment isn't a blocker - but I wonder if you know about this and if there's plans to improve on this in a second pass?

Copy link
Member Author

Choose a reason for hiding this comment

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

I am not sure how we could at this point. The ModuleMetadataBuilder is only loaded up via service loader currently and it pretty ingrained in. Unless I guess I could remove this code and add in some substrate substitutions to change constructors to reference statically defined variables instead. I am not 100% sure on that though, and I think we can add that in later if needed.

addReflectionForClass(PropertyConverter.class, true, combinedIndex, reflectiveClass, excludedClasses);

// Just add the JBossAS and Embedded TransactionManagerLookups
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, JBossStandaloneJTAManagerLookup.class));
Copy link
Member

Choose a reason for hiding this comment

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

I think you should choose one strategy and stick to it. Do we really need both JBossStandaloneJTAManagerLookup and EmbeddedTransactionManagerLookup ?

Also, I think you should auto-inject the right choice - right now I see the documentation require the user to set one, this should be unnecessary if you can require the single choice of the platform.

Copy link
Member Author

Choose a reason for hiding this comment

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

The JBossStandaloneJTAManagerLookup is so the user can link Infinispan with the transaction manager in Quarkus. The EmbeddedTransactionManagerLookup is if they just want a simple transaction manager to use outside of it.

Also, I think you should auto-inject the right choice - right now I see the documentation require the user to set one, this should be unnecessary if you can require the single choice of the platform.

Do you mean to say we should only allow the Quarkus transaction manager? Then the user wouldn't have to configure that. This would require the transaction extension always then. The embedded one is quite light weight in comparison.

Copy link
Member

Choose a reason for hiding this comment

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

Yes support only "the" transaction manager provided by the platform.

Many optimisations are made possible only because we give up on allowing people to use any weird and crazy replacement for core components: it also helps quality & people as we're accountable for the choice of implementations being made.

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 that makes my life easier as well


@Substitute
protected synchronized void addShutdownHook() {
// Don't do anything or do we want to?
Copy link
Member

Choose a reason for hiding this comment

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

probably best to log a warning.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure.

Copy link
Member Author

Choose a reason for hiding this comment

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

Looking closer, just doing nothing should be acceptable.


/**
* These substitutions need to be revisited on each new Quarkus/GraalVM release, as some methods may become
* supported. The better option currently is to use -H:+ReportUnsupportedElementsAtRuntime, which moves potential issue
Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't suggest that as as "better option" YMMV

Copy link
Member Author

Choose a reason for hiding this comment

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

This is just copied from Bela's stuff :) I can remove the comment.

Copy link
Member

Choose a reason for hiding this comment

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

yes please remove :)

<!-- Test Dependencies - Note this is not test scope as native compilation doesn't use test classes/dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-narayana-jta</artifactId>
Copy link
Member

Choose a reason for hiding this comment

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

should the quarkus-narayana-jta not be a mandated dependency? Can it run without it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, if you don't have any transactional caches it works just fine. But now that I know I should force users to only use Quarkus transaction manager I can add some more logic around this and some checks.

Copy link
Member

Choose a reason for hiding this comment

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

Please verify: does native compilation still work fine whtn the TXM is missing? I bet it won't compile ;)

Copy link
Member Author

Choose a reason for hiding this comment

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

It passes fine when I comment out this line and the testTransactionRolledBack test that failed without it.

INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.426 s - in io.quarkus.it.infinispan.embedded.InfinispanClientFunctionalityInGraalITCase

<dumpProxies>false</dumpProxies>
<!-- We have some example stack files we want to use -->
<additionalBuildArgs>
<additionalBuildArg>-H:ResourceConfigurationFiles=${project.basedir}/src/main/resources/resources-config.json</additionalBuildArg>
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't the configured stack be picked up automatically for inclusion by your extension?

I think this could hide some issues.

Copy link
Member Author

Choose a reason for hiding this comment

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

We can't because these stacks are referenced at runtime via the xml file.

Copy link
Member

Choose a reason for hiding this comment

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

ok, ic,

@@ -0,0 +1,7 @@
{
Copy link
Member

Choose a reason for hiding this comment

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

See related comment in the native-image section of the integration test's pom. I think this file should be removed.

@wburns
Copy link
Member Author

wburns commented Oct 7, 2019

hey @wburns - sorry it took so long, it's failing now if I try a rebase. I guess something changed in the meantime:

[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:0.10.0:build (default) on project quarkus-integration-test-infinispan-embedded: Failed to build a runnable JAR: Failed to build a runner jar: Failed to augment application classes: Build failure: Build failed due to errors
[ERROR] 	[error]: Build step io.quarkus.deployment.steps.ConfigurationSetup#initializeConfiguration threw an exception: java.lang.IllegalArgumentException: No Converter registered for class class io.quarkus.runtime.configuration.MemorySize

Weird it compiles just fine for me. But I didn't rebase on master yet, so it is probably related to that :) I will do that next.

@wburns
Copy link
Member Author

wburns commented Oct 7, 2019

Looks pretty good, although it doesn't take advantage of many more optimisations we could do. I wonder if you have plans for later, or if I'm missing something about the use case.

Yeah, this is the first pass only at this point. I wanted to get something that worked with configuration file that had all the options. We can trim back things and add in additional optimizations later, at least that was my thought.

@Sanne
Copy link
Member

Sanne commented Oct 7, 2019

thanks @wburns . Will you rebase and test that please?

@wburns
Copy link
Member Author

wburns commented Oct 7, 2019

@Sanne Yeah, it just finished.

Everything included native passed for me:

[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.599 s - in io.quarkus.it.infinispan.embedded.InfinispanClientFunctionalityInGraalITCase

@wburns
Copy link
Member Author

wburns commented Oct 7, 2019

Only other thing I can think of is I am using 19.2.0. Let me try rerunning tests with 19.2.0.1 and see if it causes them to fail.

@wburns
Copy link
Member Author

wburns commented Oct 7, 2019

@Sanne fixed the comments I could, rebased, and tested and everything passed for me.

@Sanne
Copy link
Member

Sanne commented Oct 8, 2019

Thanks @wburns . Trying again, let's see if I can figure it out quickly - I hope so as I'm supposed to work on some other urgent stuff :/

@Sanne
Copy link
Member

Sanne commented Oct 8, 2019

@wburns could you tell me which version of the plugin you have logged when invoking

 mvn io.quarkus:quarkus-maven-plugin:help

?

In my case it defaults to a very old version. So I think I have two problems:

  • why is my system default using a very old tag (and this is probably unrelated from your PR)
  • why is it not using the project version when I'm testing your module (could be related to your PR?)

@Sanne
Copy link
Member

Sanne commented Oct 8, 2019

@wburns I pushed two additional commits, the second one ensures the right version of the plugin is picked up.

@Sanne
Copy link
Member

Sanne commented Oct 8, 2019

See also #3832

@wburns
Copy link
Member Author

wburns commented Oct 8, 2019

@Sanne changes seem fine to me, is there anything else you needed me to do to integrate?

@Sanne
Copy link
Member

Sanne commented Oct 8, 2019

@wburns no I think we're good, just hoping to actually get to try the native-image out..

<stack name="tcpping" extends="tcp">
<MPING ispn:stack.combine="REMOVE" xmlns="urn:org:jgroups"/>
<TCPPING async_discovery="true"
initial_hosts="${initial_hosts:192.168.1.20[7800],192.168.1.20[7801]}"

Choose a reason for hiding this comment

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

Hardcoding addresses here doesn't seem like a good idea to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is just for the tests to ensure proper parsing. It isn't actually used.

@wburns
Copy link
Member Author

wburns commented Oct 10, 2019

@Sanne I added a simple test that starts up 3 nodes and ensures they join together. This passed on both JVM and native mode for me.

@Sanne Sanne merged commit 921a2c6 into quarkusio:master Oct 11, 2019
@Sanne Sanne added this to the 0.25.0 milestone Oct 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants