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

DeployableVerticle and multiple instances ... #2

Closed
ghost opened this issue Mar 22, 2018 · 3 comments
Closed

DeployableVerticle and multiple instances ... #2

ghost opened this issue Mar 22, 2018 · 3 comments

Comments

@ghost
Copy link

ghost commented Mar 22, 2018

I've been playing around a bit with this library for integrating Spring and Vertx, and its been a great help, and pretty seamlessly integrates the two.

I'm having on issue I've been messing around with for a bit of time, and haven't figured out. I'm starting to think there isn't a way to do it...

I'm trying to have a code-defined set of deployment options via the DeployableVerticle interface. Although the docs don't say so, as far as I can tell that isn't supported with auto-registered Verticles, they have to be manual. That's fine. However, if I use a @bean annotation on a getMyVerticle() call, DeployableVerticle isn't used. I can put a @VerticleDeployment(instances=4) and get four instances as long as I use @scope("prototype"). To get DeployableVerticle to work, I need to use a VerticleRegistrationBean, but the @scope there gets picked up by Spring for that bean, not the MyVerticle bean created inside of it, so DeployableVerticle is used to configure the deployment, but I can't actually set instances > 1 I get this error:

org.springframework.context.ApplicationContextException: Failed to start bean 'vertx'; nested exception is java.lang.IllegalArgumentException: Can't specify > 1 instances for already created verticle

So is there some "magic" that I'm missing that can get that working together? My specific goal for this is this, however I'm sure it'll come up for other use cases:

@Override public DeploymentOptions getDeploymentOptions() { return new DeploymentOptions() .setHa(true) // highly available .setInstances(Runtime.getRuntime().availableProcessors()) // one instance per CPU ; }

Basically setting the instances at runtime to the number of available cores.

Any tips/suggestions?

@tkrullmann
Copy link
Member

tkrullmann commented Mar 22, 2018

Hi! Glad that you find the library useful.
The HA deployment of verticles is probably the part that maps worst to Spring, so I'm sure it could still use some improvement. I will check it out when I find some time!

In the meantime, something you could try is to

  • declare your verticle as a prototype bean
  • declare another bean of type VerticleRegistrationBean that uses the verticle name "spring:<beanName>" (and doesn't set a verticle instance). This library registers a verticle factory for the prefix spring: for that case.

@tkrullmann
Copy link
Member

I know that wiring beans by name seems a bit outdated, but when using HA and > 1 verticle instances, Vert.x needs to take full control of the creation of the verticle - only way that works is with prototype beans, which have to be referenced by name, or FactoryBeans (there should be an example in the docs too).

@ghost
Copy link
Author

ghost commented Mar 23, 2018

Thanks, that sent me down the right path.

For anyone else who runs into this, and is confused, here's how it works:

`
@bean("spring:httpServerVerticle")
@scope("prototype")
@VerticleDeployment(false)
public HttpServerVerticle httpServerVerticle()
{
return new HttpServerVerticle();
}

@Bean
public VerticleRegistrationBean httpServerRegistrationBean()
{
	return new VerticleRegistrationBean("spring:httpServerVerticle")
			.setDeploymentOptions(new DeploymentOptions()
			.setHa(true) // highly available
			.setInstances(Runtime.getRuntime().availableProcessors())); // one instance per CPU
}

`

Basically like that.

One gotcha -- VerticleRegistrationBean only uses the DeployableVerticle interface if the (Verticle) constructor is used, not the (String) constructor, so you have to set the options like above, it can't be done in the bean.

Not sure if that's a bug or an intended behavior. There's sort of a catch-22 because you need an instance to call the method, and you can't create the instance without the results from it, so I assume that's as-intended. It may be worth mentioning in the docs, though. They've got a lot of "you can do this, or this, or this", but don't mention "you can't do this, if you do that".

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant