Multiple instances cf applications create multiple instances of flowable-engine as well

Hello Flowable Team,

I’ve deployed an application in CF with bpmn. Now I’m adding/reducing the number of instances of the application based on the load on it, but the issue is, with new application instance, there is a new flowable-engine getting created. So the process instance which was created by engine1 is not recognized by engine2.

But according to my scenario, I need only one flowable-engine for any number of application instances. Is it possible somehow, following are the ways which I can think of,

  1. One separate application with flowable bpmn which can be consumed by other applications instances
  2. any configuration which can limit the flowable-engine to 1 regardless of how many instances of an application I have (if there is something available like this)

Regards,
Ashmita Sinha

Multiple instances of the engines pointing at the same data source should have a shared knowledge of process instances. Are you using different datasources for flowable in each instance of your microservice?

If you don’t need the engine to scale along with other aspects of the microservices, you can separate them and use the REST interface to interact with the engine. I would still recommend having at least two instances for high availability.

I don’t think this is possible, the standard way to do that with microservices is to separate logic that does not need to scale at the same time into different services.

Will

Hello @wwitt,

I’m using the same datasource and in this case, according to you all the flowable-engines should point to a shared knowledge to get the information about process instance.

In my scenario,

  1. I’ve one call to create the process instance
  2. The second call starts that process instance by id and proceed

But I found that another instance of the application(where the new instance of flowable-engine also got created) was unable to recognize the process instance id, even though the datasource is same. This is the way => https://www.flowable.org/docs/userguide/index.html#springSpringBoot I’ve used to create the process engine(using beans).

What could be the possible reason?

Regards,
Ashmita Sinha

I see two possibilities:

  1. There’s a misconfiguration that is causing you to believe they are pointed at the same database but you aren’t actually
  2. The process has either not hit a wait state so that the database transaction can finish or the process has already finished (possibly due to an error).

Some questions:

  • What database are you using? In memory databases like H2 are not shared between instances and cane cause behavior like this.
  • If you just used the starter did you perform any custom configuration or initialization of the process engine? If so, can you share it?

Will

Hello @wwitt

Answer to your questions,

  • I’m using postgres db which I believe should be shared between the instances and not cause the problem

  • Here’s the class for flowable configuration which i’ve created

public class FlowableEngineConfiguration {

private final Logger logger = LoggerFactory.getLogger(FlowableEngineConfiguration.class);

@Autowired
public DataSource dataSource;

@Autowired
CASPostgresDbProvider casPostgresDbProvider;

@Autowired
CASDbService casDbService;

private void init() {
    casDbService.updateAdminTenant();
}

@Bean(name = "processEngineConfiguration")
public ProcessEngineConfigurationImpl processEngineConfiguration(){
    init();
    javax.sql.DataSource ds = (javax.sql.DataSource) dataSource;
    SpringProcessEngineConfiguration processEngineConfiguration = new SpringProcessEngineConfiguration();
    processEngineConfiguration.setDatabaseSchema(casPostgresDbProvider.SCHEMA_NAME);
    processEngineConfiguration.setDataSource(ds);
    processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
    processEngineConfiguration.setTransactionManager(annotationDrivenTransactionManager());
    logger.info("processEngineConfiguration bean created");
    return processEngineConfiguration;
}

@Bean(name = "ProcessEngine")
public ProcessEngine processEngine(){
    try{
        logger.info("ProcessEngine bean created");
        return processEngineConfiguration().buildProcessEngine();
    }catch(Exception e){
        throw new RuntimeException(e);
    }
}

@PostConstruct
public void deployDefinedProcess(){
    repositoryService().createDeployment().name("myprocess")
            .addClasspathResource("/processes/myprocess.bpmn20.xml").deploy();
}

@Bean(name = "transactionManager")
public PlatformTransactionManager annotationDrivenTransactionManager(){
    DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
    javax.sql.DataSource ds = (javax.sql.DataSource) dataSource;
    transactionManager.setDataSource(ds);
    logger.info("transactionManager bean created");
    return transactionManager;
}

@Bean
public RepositoryService repositoryService(){
    return processEngine().getRepositoryService();
}

}

Regards,
Ashmita Sinha

I’m assuming that you are you’re binding the database service and allowing the app to pick up the auto-configured credentials. I know I’ve had some trouble getting the app to pick up the connection information. Can you verify you have the correct spring cloud dependencies?

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-spring-service-connector</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-cloudfoundry-connector</artifactId>
        </dependency>

Hello @wwitt

Yes, you’re right. There is a postgres db instance which I’ve binded with my application.

And, I’ve added “spring-cloud-cloudfoundry-connector” in my pom but not the other one. How would these dependencies would help?

Regards,
Ashmita Sinha

spring-cloud-spring-service-connector may not be strictly required it looks like its dependencies are in spring-cloud-cloudfoundry-connector. They are the method that the bound VCAP_SERVICES provided to the app by CF get turned into datasources. My theory is this:

  • Looking for a process by process id is simply a call to the database
  • If one instance of the service can see the process but the other cannot, they must not be looking at the same database
  • I have personally had issues getting Spring Boot applications detecting and using CF’s bound datasources if I did not use the correct dependencies.
1 Like

Hello @wwitt

In that case should look the datasource which is getting created, whether it’s the same or not?

Few questions which I have:

  1. But is it possible that while creating multiple instances of an application, new datasource would be created which is then used for the creation of flowable engine?
  2. Are the configurations right for flowable engine, is there any chance the configurations which I’ve made can cause any issues later?

Regards,
Ashmita Sinha

Looking back at your configuration, this line seems like it might be suspect:

processEngineConfiguration.setDatabaseSchema(casPostgresDbProvider.SCHEMA_NAME);

What does CASPostgresDbProvider do? is it possible that different instances are getting different schemas?

SCHEMA_NAME is just a final string where datasource name is defined. And, casPostgresDbProvider is an autowired object of class where SCHEMA_NAME is defined.

Hello @wwitt

I learnt that when a new instance of an application gets created in cloud foundry, new data source is also created but it points to the same database.

So, if I’ll try to picture the whole scenario,

multiple application instances ==> multiple datasources ==> multiple flowable-engines ==> one database

ultimately we have only one database which should not cause any problem right?

Regards,
Ashmita Sinha

That shouldn’t be a problem, as long as the schema gets set as a first thing in the connection.