Connecting across a list of brokers no longer means recompiling the library. The failover: transport is now switched on at runtime, per connection, through a small interface on IConnection.

Why the define had to go

Habari has long understood a failover connection URL — failover:(stomp://a,stomp://b) — that tries each broker in turn and reconnects with backoff when a connection can not be established. Until now the feature sat behind a conditional define, HABARI_ENABLE_FAILOVER_PROTOCOL.

That carried three costs:

  • every consumer had to rebuild the whole library with a matching define, and keep it set across upgrades;
  • it was all‑or‑nothing — you could not enable failover for one connection and not another;
  • whether a build supported failover: URLs was invisible at runtime, so a missing define surfaced only as an “Unsupported Protocol” error in production.

A connection setting belongs in the connection API, not in the build configuration. So it moved.

The interface

IFailoverProtocol is declared in BTMgmtInterfaces, alongside IConnectionInfo. Every IConnection implements it.

BTMgmtInterfaces.pas

IFailoverProtocol = interface(IInterface)
  ['{7C4B1E90-2A6D-4F1B-9C3E-1D8A5B0F2E44}']
    function GetEnableFailoverProtocol: Boolean;
    procedure SetEnableFailoverProtocol(const Value: Boolean);
    property EnableFailoverProtocol: Boolean
      read GetEnableFailoverProtocol write SetEnableFailoverProtocol;
end;

Set it after creating the connection and before starting it:

Enabling failover from code

uses
  BTMQInterfaces, BTMgmtInterfaces, BTConnectionFactory;

var
  Factory: IConnectionFactory;
  Connection: IConnection;
begin
  Factory := TBTConnectionFactory.Create(
    'failover:(stomp://broker-1:61613,stomp://broker-2:61613)'
    + '?initialReconnectDelay=1000&maxReconnectAttempts=10');

  Connection := Factory.CreateConnection;
  (Connection as IFailoverProtocol).EnableFailoverProtocol := True;
  Connection.Start;
end;

Before and after

Until now

{ project-wide define, whole library rebuilt }
-dHABARI_ENABLE_FAILOVER_PROTOCOL

Connection := Factory.CreateConnection;
Connection.Start;   { failover: works everywhere }

One build-time switch governs every connection in the process. Absent it, a failover: URL throws.

From this release

{ no define, no rebuild }

Connection := Factory.CreateConnection;
(Connection as IFailoverProtocol)
  .EnableFailoverProtocol := True;
Connection.Start;

Each connection opts in on its own. The capability is discoverable by querying the interface.

Failover URLs, unchanged

The URL grammar and its tuning parameters are exactly as before — only the switch that activates them has changed. A failover URL wraps a comma‑separated broker list in failover:(…), with options appended after the closing parenthesis.

ParameterDefaultEffect
initialReconnectDelay10 msPause before the first reconnect attempt.
maxReconnectDelay30000 msUpper bound on the delay once it has backed off.
backOffMultiplier2.0The delay is multiplied by this factor after each failed pass through the list.
maxReconnectAttempts−1Attempts before giving up. −1 retries forever; 0 disables retrying.
randomizetrueBegin from a random entry in the broker list rather than the first.

Migrating

  1. Drop HABARI_ENABLE_FAILOVER_PROTOCOL from your project options and build scripts.
  2. After each CreateConnection that uses a failover: URL, cast to IFailoverProtocol and set EnableFailoverProtocol := True before Start.
  3. Rebuild your application. The library itself needs no special build.

Backwards compatible

If HABARI_ENABLE_FAILOVER_PROTOCOL is still defined, every connection starts with EnableFailoverProtocol already True, and the compiler emits a hint pointing you to the property. Existing code keeps working — migrate when it suits you.

Rules of the road

  • Set it before the connection starts. Assigning EnableFailoverProtocol on an already‑connected client raises EMQException.
  • failover: URL with the flag off still throws the “Unsupported Protocol” exception on connect — now with a hint to set the property.
  • Plain stomp:// URLs are unaffected; the flag only matters when the protocol is failover:.