Skip to content

Implement MessageQueue for MySQL/MariaDB (@fedify/mysql) #586

@dahlia

Description

@dahlia

Summary

Add a MysqlMessageQueue class to the @fedify/mysql package, implementing the MessageQueue interface backed by MySQL or MariaDB.

Motivation

Developers already using MySQL or MariaDB as their primary database should be able to use it as a Fedify message queue backend without introducing additional infrastructure such as Redis or RabbitMQ. This complements the MysqlKvStore implementation in the same package (#585).

Proposed API

import { createFederation } from "@fedify/fedify";
import { MysqlMessageQueue } from "@fedify/mysql";
import mysql from "mysql2/promise";

const pool = mysql.createPool("mysql://user:pass@localhost/db");
const federation = createFederation<void>({
  queue: new MysqlMessageQueue(pool),
  // ...
});

Implementation notes

  • Unlike PostgresMessageQueue, which benefits from PostgreSQL's LISTEN/NOTIFY for real-time message delivery, MySQL and MariaDB have no equivalent mechanism. The implementation should use polling instead.
  • SELECT ... FOR UPDATE SKIP LOCKED should be used to safely dequeue messages in concurrent multi-worker environments without contention. This syntax is available from MySQL 8.0 and MariaDB 10.6.
  • The polling interval should be configurable, with a sensible default (e.g., 1 second).
  • Delayed message delivery (the delay option in MessageQueueEnqueueOptions) should be supported by storing a deliver_after timestamp and skipping messages that are not yet due.
  • The enqueueMany() method should be implemented for better performance when enqueuing multiple messages at once.
  • The nativeRetrial property should be false, as retry logic is handled by Fedify itself.
  • Document the polling-based nature of this implementation and its latency characteristics compared to PostgresMessageQueue.

Checklist

  • Implement MysqlMessageQueue class in the @fedify/mysql package
  • Support enqueue(), enqueueMany(), and listen() with polling
  • Support delayed delivery via deliver_after timestamp
  • Write unit tests (with a real MySQL/MariaDB instance via Docker)
  • Document the new MessageQueue in docs/manual/mq.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status

    Backlog

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions