flowable / flowable-engine

A compact and highly efficient workflow and Business Process Management (BPM) platform for developers, system admins and business users.
https://www.flowable.org
Apache License 2.0
7.95k stars 2.62k forks source link

Incoming event starts process for suspended process definition #3601

Open wvlancke opened 1 year ago

wvlancke commented 1 year ago

Describe the bug I have set up a process definition with a start event using the event registry linked to a RabbitMQ channel.

Everything works as expected when sending a message to the RabbitMQ queue.

Afterwards, I suspend the process definition and I send a message to the RabbitMQ queue again.

The message receiver will try to start a process but fails to do so due to the process definition being suspended. The RabbitMQ message is then considered to be in error and is retried, creating an infinite loop.

Expected behavior I would expect starting a process from a suspended process definition id not to happen, or having the event subscription to no longer match the given process definition.

If there is any workaround for this, I would be happy to try this as well.

Additional context Using Flowable 6.8.0 Using Flowable within Spring Boot

chaserb commented 10 months ago

@wvlancke , I don't know of a workaround to cancel a suspended definition's subscription. I do, however, have a workaround for the infinite loop. Since you're using Spring Boot, have you considered declaring a dead letter exchange when configuring your inbound queue? For example:

    @Bean
    public Queue workflowInboundQueue(final MyApplicationProperties props) {
        return QueueBuilder.durable(props.getInboundQueue())
                .withArgument("x-dead-letter-exchange", props.getInboundQueueDLX())
                .build();
    }

For truly undeliverable messages, this will send them to your dead letter exchange instead of back to your inbound queue.

Another side effect of the exception you've encountered is that other process definitions subscribed to the same event may fail to execute. Whether they execute depends on the order in which the BpmnEventRegistryEventConsumer processes the subscriptions in its eventReceived() method. Subscriptions processed before the suspended definition will likely succeed, subscriptions after it will never be processed because the FlowableException thrown stops the subscriptions loop. This is true regardless of whether you've configured your Process Engine for asynchronous initiation of Event Registry events: processConfig.setEventRegistryStartProcessInstanceAsync(true);

To work around this side effect, I've extended the BpmnEventRegistryEventConsumer with an eventReceived() override to process each subscription in a try/catch structure, and then set it in my Process Engine configuration: processConfig.setEventRegistryEventConsumer(new DecoupledBpmnEventRegistryEventConsumer(processConfig));