POE::Component::MessageQueue::Storage::Generic::DBI -- A storage engine that uses DBI


  use POE;
  use POE::Component::MessageQueue;
  use POE::Component::MessageQueue::Storage::Generic;
  use POE::Component::MessageQueue::Storage::Generic::DBI;
  use strict;

  # For mysql:
  my $DB_DSN      = 'DBI:mysql:database=perl_mq';
  my $DB_USERNAME = 'perl_mq';
  my $DB_PASSWORD = 'perl_mq';
  my $DB_OPTIONS  = undef;

    storage => POE::Component::MessageQueue::Storage::Generic->new({
      package => 'POE::Component::MessageQueue::Storage::DBI',
      options => [{
        # if there is only one DB server
        dsn      => $DB_DSN,
        username => $DB_USERNAME,
        password => $DB_PASSWORD,
        options  => $DB_OPTIONS,

        # OR, if you have multiple database servers and want to failover
        # when one goes down.

        #servers => [
        #  {
        #    dsn => $DB_SERVER1_DSN,
        #    username => $DB_SERVER1_USERNAME,
        #    password => $DB_SERVER1_PASSWORD,
        #    options  => $DB_SERVER1_OPTIONS
        #  },
        #  {
        #    dsn => $DB_SERVER2_DSN,
        #    username => $DB_SERVER2_USERNAME,
        #    password => $DB_SERVER2_PASSWORD,
        #    options  => $DB_SERVER2_OPTIONS
        #  },



A storage engine that uses DBI. All messages stored with this backend are persistent.

This module is not itself asynchronous and must be run via POE::Component::MessageQueue::Storage::Generic as shown above.

Rather than using this module "directly" [1], I would suggest wrapping it inside of POE::Component::MessageQueue::Storage::FileSystem, to keep the message bodys on the filesystem, or POE::Component::MessageQueue::Storage::Complex, which is the overall recommended storage engine.

If you are only going to deal with very small messages then, possibly, you could safely keep the message body in the database. However, this is still not really recommended for a couple of reasons:

  • All database access is conducted through POE::Component::Generic which maintains a single forked process to do database access. So, not only must the message body be communicated to this other proccess via a pipe, but only one database operation can happen at once. The best performance can be achieved by having this forked process do as little as possible.

  • A number of databases have hard limits on the amount of data that can be stored in a BLOB (namely, SQLite, which sets an artificially lower limit than it is actually capable of).

  • Keeping large amounts of BLOB data in a database is bad form anyway! Let the database do what it does best: index and look-up information quickly.


dsn => SCALAR
username => SCALAR
password => SCALAR
options => SCALAR
servers => ARRAYREF

An ARRAYREF of HASHREFs containing dsn, username, password and options. Use this when you have serveral DB servers and want Storage::DBI to failover when one goes down.

mq_id => SCALAR

A string which uniquely identifies this MQ. This is required when running two MQs which use the same database. If they don't have unique mq_id values, than one MQ could inadvertently clear the claims set by the other, causing messages to be delivered more than once.



Ignored. All messages are persisted.


Ignored. All messages are kept until handled.


Fully Supported.



By "directly", I still mean inside of POE::Component::MessageQueue::Storage::Generic because that is the only way to use this module.


POE::Component::MessageQueue, POE::Component::MessageQueue::Storage, DBI

Other storage engines:

POE::Component::MessageQueue::Storage::Memory, POE::Component::MessageQueue::Storage::BigMemory, POE::Component::MessageQueue::Storage::DBI, POE::Component::MessageQueue::Storage::FileSystem, POE::Component::MessageQueue::Storage::Generic, POE::Component::MessageQueue::Storage::Throttled, POE::Component::MessageQueue::Storage::Complex, POE::Component::MessageQueue::Storage::Default