ballerina-platform / ballerina-library

The Ballerina Library
https://ballerina.io/learn/api-docs/ballerina/
Apache License 2.0
136 stars 64 forks source link

[Bug] [RabbitMQ] rabbitmq:Listener trying to re-declare the queue internally with mismatching settings #6629

Closed aashikam closed 5 months ago

aashikam commented 5 months ago

Description: RabbitMQ listener queue declare existing functionality is based on the assumption that the queue already exists in the server at the time the listener subscribes to it, otherwise it will declare that queue with default settings. Declaration with default settings was added as RabbitMQ claims that the queue declare function is idempotent and does not re-declare existing queues. But the observed behavior in a recent issue is that it will raise an error if there is a mismatch between the existing queue and the queue that is re-declared.

Steps to reproduce: Declare a durable = true queue in the RabbitMQ server named for example "demo"

Try to listen to it with the service config:

@rabbitmq:ServiceConfig {
    queueName: "demo"
}

API changes/additions: There are two approaches to fix the issue:

  1. Remove declaring the queue on the listener side - [Breaking]
  2. Add complete queue settings individually to the service config of the listener - [API ADDITION]

Existing client API:

   isolated remote function queueDeclare(string name, QueueConfig? config = ()) returns Error? {}

  # Additional configurations used to declare a queue.
  #
  # + durable - Set to true if declaring a durable queue
  # + exclusive - Set to true if declaring an exclusive queue
  # + autoDelete - Set to true if declaring an auto-delete queue
  # + arguments - Other properties (construction arguments) of the queue
  public type QueueConfig record {|
      boolean durable = false;
      boolean exclusive = false;
      boolean autoDelete = true;
      map<anydata> arguments?;
  |};

Change to service config:

# Configurations required to create a subscription.
#
# + queueName - The name of the queue to be subscribed
# + config - The configurations required to declare a queue
# + autoAck - If false, should manually acknowledge
public type RabbitMQServiceConfig record {|
    string queueName;
    QueueConfig config;
    boolean autoAck = true;
|};

Going with the second approach.

Sample usage:

@rabbitmq:ServiceConfig {
    queueName: "demo",
    config:  {
        durable: true,
        autoDelete: false,
        exclusive: false
    }
}
service rabbitmq:Service on new rabbitmq:Listener(rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT) {

    remote function onMessage(rabbitmq:AnydataMessage msg) returns error? {
      // process
    }
}
github-actions[bot] commented 5 months ago

This issue is NOT closed with a proper Reason/ label. Make sure to add proper reason label before closing. Please add or leave a comment with the proper reason label now.

      - Reason/EngineeringMistake - The issue occurred due to a mistake made in the past.
      - Reason/Regression - The issue has introduced a regression.
      - Reason/MultipleComponentInteraction - Issue occured due to interactions in multiple components.
      - Reason/Complex - Issue occurred due to complex scenario.
      - Reason/Invalid - Issue is invalid.
      - Reason/Other - None of the above cases.