8.3. Using Custom Lockers

Overview

If one of the provided lockers are not sufficient for your needs, you can implement a custom locker. All lockers are implementations of the Red Hat JBoss A-MQ Locker interface. They are attached to the persistence adapter as a spring bean in the locker element.

Interface

All lockers are implementations of the org.apache.activemq.broker.Locker interface. Implementing the Locker interface involves implementing seven methods:
  • boolean keepAlive()
        throws IOException;
    Used by the lock's timer to ensure that the lock is still active. If this returns false, the broker is shutdown.
  • void setLockAcquireSleepInterval(long lockAcquireSleepInterval);
    Sets the delay, in milliseconds, between attempts to acquire the lock. lockAcquireSleepInterval is typically supplied through the locker's XML configuration.
  • public void setName(String name);
    Sets the name of the lock.
  • public void setFailIfLocked(boolean failIfLocked);
    Sets the property that determines if the broker should fail if it cannot acquire the lock at start-up. failIfLocked is typically supplied through the locker's XML configuration.
  • public void configure(PersistenceAdapter persistenceAdapter)
        throws IOException;
    Allows the locker to access the persistence adapter's configuration. This can be used to obtain the location of the message store.
  • void start();
    Executed when the locker is initialized by the broker. This is where the bulk of the locker's implementation logic should be placed.
  • void stop();
    Executed when the broker is shutting down. This method is useful for cleaning up any resources and ensuring that all of the locks are released before the broker is completely shutdown.

Using AbstractLocker

To simplify the implementation of lockers, Red Hat JBoss A-MQ includes a default locker implementation, org.apache.activemq.broker.AbstractLocker, that serves as the base for all of the provided lockers. It is recommended that all custom locker implementations also extand the AbstractLocker class instead of implementing the plain Locker interface.
AbstractLocker provides default implementations for the following methods:
  • keepAlive()—returns true
  • setLockAcquireSleepInterval()—sets the parameter to the value of the locker beans' lockAcquireSleepInterval if provided or to 10000 if the parameter is not provided
  • setName()
  • setFailIfLocked()—sets the parameter to the value of the locker beans' failIfLocked if provided or to false if the parameter is not provided
  • start()—starts the locker after calling two additional methods
    Important
    This method should not be overridden.
  • stop()—stops the locker and adds a method that is called before the locker is shutdown and one that is called after the locker is shutdown
    Important
    This method should not be overridden.
AbstractLocker adds two methods that must be implemented:
  • void doStart()
        throws Exception;
    Executed as the locker is started. This is where most of the locking logic is implemented.
  • void doStop(ServiceStopper stopper)
        throws Exception;
    Executed as the locker is stopped. This is where locks are released and resources are cleaned up.
In addition, AbstractLocker adds two methods that can be implemented to provide additional set up and clean up:
  • void preStart()
        throws Exception;
    Executed before the locker is started. This method can be used to initialize resources needed by the lock. It can also be used to perform any other actions that need to be performed before the locks are created.
  • void doStop(ServiceStopper stopper)
        throws Exception;
    Executed after the locker is stopped. This method can be used to clean up any resources that are left over after the locker is stopped.

Configuration

Custom lockers are added to a persistence adapter by adding the bean configuration to the persistence adapter's locker element as shown in Example 8.6, “Adding a Custom Locker to a Persistence Adapter”.

Example 8.6. Adding a Custom Locker to a Persistence Adapter

<persistenceAdapter>
  <kahaDB directory = "target/activemq-data">
    <locker>
      <bean class="my.custom.LockerImpl">
        <property name="lockAcquireSleepInterval" value="5000" />
        ...
      </bean
    </locker>
  </kahaDB>
</persistenceAdapter>