Skip to content
SynGo-DPublic

About

RabbitMQ-based messaging infrastructure for asynchronous communication between microservices in the Automated Code Review and Technical Debt Tracking Dashboard.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

14 Commits

Folders and files

Repository files navigation

RabbitMQ

This is the shared RabbitMQ communication layer for the CodePulse backend microservices. It is not a service that does any code review or debt calculation itself - it just gives every other microservice (Webhook Listener, Worker, Analysis Engine, Result Collector, Debt Calculation, Notification, Main Backend) a simple, consistent way to publish and consume messages through RabbitMQ.

What's in here

src/
  app.ts                 Small Express app used for local testing (health check, test-publish route)
  server.ts              Entry point - connects to RabbitMQ, then starts the Express app
  rabbitmq/
    connection.ts        Opens/holds the RabbitMQ connection and channel, auto-reconnects
    publisher.ts         publish(queue, message) - send a message to a queue
    consumer.ts           consume(queue, handler) - listen to a queue, with retry + dead-letter handling
    deadletter.ts        onDeadLetter(queue, handler) - handle messages that failed after retries
    queues.ts             The list of every queue name used across the system
    types.ts               TypeScript interfaces describing what each queue's messages look like
    index.ts               initializeRabbitMQ() - connects and declares all queues

Running it locally

  1. Make sure RabbitMQ is running (for example, via Docker):
    docker run -d --hostname rabbitmq --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management
    
  2. Copy .env.example to .env and adjust RABBITMQ_URL if needed.
  3. Install dependencies and start the dev server:
    npm install
    npm run dev
    
  4. Check http://localhost:5000/health - it should report "rabbitmq": "connected".

How to use this from another service

Publishing a message

import { publish } from "./rabbitmq/publisher";
import { QUEUES } from "./rabbitmq/queues";
import type { PRJob } from "./rabbitmq/types";

const job: PRJob = {
    repository: "SynGo-D/example-repo",
    cloneUrl: "https://github.com/SynGo-D/example-repo.git",
    commit: "abc123",
    branch: "main",
    prNumber: 42,
    provider: "github",
    timestamp: new Date().toISOString(),
};

await publish(QUEUES.PR_QUEUE, job);

Consuming messages

import { consume } from "./rabbitmq/consumer";
import { QUEUES } from "./rabbitmq/queues";

await consume(QUEUES.PR_QUEUE, async (data) => {
    // `data` is already parsed from JSON here.
    // Throw an error if the message couldn't be processed -
    // consume() will take care of retrying or dead-lettering it.
});

Handling dead-lettered messages

When a message fails 3 times, it's moved to a dead-letter queue. Register a handler to be notified:

import { onDeadLetter } from "./rabbitmq";
import { QUEUES } from "./rabbitmq/queues";

await onDeadLetter(QUEUES.PR_QUEUE, async (data, metadata) => {
    // Message failed after 3 retries
    console.error("PR job permanently failed:", {
        repository: data.repository,
        prNumber: data.prNumber,
        failureReason: metadata.failureReason,
        retryCount: metadata.retryCount,
    });
    
    // You can:
    // - Send an alert to Slack/PagerDuty
    // - Store in a database for manual review
    // - Create a ticket for investigation
    // - Forward to an admin service
});

See DEAD_LETTER_GUIDE.md for detailed documentation on dead-letter queues.

Queues

See src/rabbitmq/queues.ts for the full, commented list of queues and which two services each one connects. The message shape carried by each queue is documented in src/rabbitmq/types.ts.

Reliability behaviour

  • Reconnects automatically. If the connection to RabbitMQ drops, connection.ts retries every 5 seconds and re-declares queues / re-subscribes consumers once it's back.
  • Retries failed messages. If a consume() handler throws, the message is retried up to 3 times.
  • Dead-letters messages that keep failing. After 3 failed attempts, the message is moved to <queue-name>.dead_letter instead of being retried forever, so it doesn't block the queue.
  • Shuts down gracefully. On SIGINT/SIGTERM (e.g. Ctrl+C, or Docker/Kubernetes stopping the container), the RabbitMQ connection is closed cleanly before the process exits.

Environment variables

Variable Description
PORT Port the Express app listens on
RABBITMQ_URL Connection string for the RabbitMQ server

About

RabbitMQ-based messaging infrastructure for asynchronous communication between microservices in the Automated Code Review and Technical Debt Tracking Dashboard.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages