rayman
rayman

Reputation: 21616

Setting multiple instances for Verticles using vertx embedded and Guice

I am using Vertx cluster on the same machine(dev mode). I am using guice to Inject some pojo's as well.

However when I try to increase Verticle instances I get:

java.lang.IllegalArgumentException: Can't specify > 1 instances for already created verticle
    at io.vertx.core.impl.DeploymentManager.deployVerticle(DeploymentManager.java:70)
    at io.vertx.core.impl.VertxImpl.deployVerticle(VertxImpl.java:516)
    at io.vertx.core.impl.VertxImpl.deployVerticle(VertxImpl.java:511)
    at com.mycompany.world_map_service.web.starter.StarterVerticle.lambda$main$0(StarterVerticle.java:39)

This is How I configure it:

 public static void main(String[] args) throws Exception {

        final Logger logger = Logger.getLogger(StarterVerticle.class);


        ClusterManager mgr = new HazelcastClusterManager();
        VertxOptions options = new VertxOptions().setClusterManager(mgr);
        Vertx.clusteredVertx(options, res -> {
            DeploymentOptions deploymentOptions = new DeploymentOptions().setConfig(config);
            if (res.succeeded()) {
                Vertx vertx = res.result();
                //  Injector injector = Guice.createInjector(new AppInjector(vertx));
                Injector injector = Guice.createInjector(new AppInjector(vertx, deploymentOptions));
                vertx.deployVerticle(injector.getInstance(VertxHttpServerVerticle.class), deploymentOptions.setInstances(3));
                ...
}

Thats my AppInjector class:

public class AppInjector extends AbstractModule {

    private Vertx vertx = null;
    private Context context = null;
    DeploymentOptions deploymentOptions = null;


    public AppInjector(Vertx vertx, DeploymentOptions deploymentOptions) {
        this.vertx = vertx;
        this.context = vertx.getOrCreateContext();
        this.deploymentOptions = deploymentOptions;
    }


    @Override
    protected void configure() {
        bind(LocationService.class).to(LocationServiceImpl.class).in(Singleton.class);
        bind(LocationServiceDAO.class).to(LocationServiceDaoImpl.class).in(Singleton.class);
        bind(RedisRepo.class).toProvider(() -> {
            return new RedisRepo(deploymentOptions.getConfig());
        });
        bind(Neo4jRepo.class).toProvider(() -> {
            return new Neo4jRepo(deploymentOptions.getConfig());
        });
    }
}

Any idea why I get collision ? I know that I should use by name: com.mycompany.world_map_service.web.http.VertxHttpServerVerticle but than if I inject dependencies they are going to be duplicated for each instance, won't they?

Upvotes: 3

Views: 3940

Answers (2)

Raju Garande
Raju Garande

Reputation: 1

If you have single verticle and want to run that with more than 1 instance, you can achieve that using lambda. (this is beginner friendly)


Vertx.vertx().deployVerticle(() -> new HelloVerticle(), new DeploymentOptions().setInstances(2))

Upvotes: 0

gordysc
gordysc

Reputation: 334

I know I'm a bit late here, but here's the "why" for someone maybe down the road that finds this question. Follow the error message:

Can't specify > 1 instances for already created verticle

You're creating an instance of the Verticle using Guice, and then trying to deploy 3 instances, but you've already created a Verticle instance:

vertx.deployVerticle(injector.getInstance(VertxHttpServerVerticle.class), deploymentOptions.setInstances(3));

This is why you want to pass the class name. You can see the flow in io.vertx.core.impl.DeploymentManager which explains the above error as well.

I know that I should use by name: "com.mycompany.world_map_service.web.http.VertxHttpServerVerticle" but than if I inject dependencies they going to be duplicated for each instance wont they?

I'm not sure what you mean by this. If you don't want to duplicate data/dependencies for some reason, perhaps you could involve another object, or singleton, or leverage Vertx's Shared Data?

Upvotes: 1

Related Questions