Skip to content

Phase 4: Global message registry with conflict detection #2804

Description

@drazisil

Summary

Create a global message registry that detects duplicate handler registrations at startup, providing a single source of truth for all message handlers.

Background

Current state:

  • Each service has its own MessageHandlerRegistry singleton
  • Same opCode can be registered in multiple places (e.g., 0x106 in both lobby registry and npsCommandHandlers)
  • No startup-time detection of conflicts
  • Difficult to get full picture of all supported messages

Proposed Solution

// packages/shared/src/handlers/GlobalMessageRegistry.ts

interface RegisteredHandler {
    port: number;
    opCode: number;
    name: string;
    service: string;
}

class GlobalMessageRegistry {
    private static instance: GlobalMessageRegistry;
    private readonly handlers = new Map<string, RegisteredHandler>();

    static getInstance(): GlobalMessageRegistry {
        if (!GlobalMessageRegistry.instance) {
            GlobalMessageRegistry.instance = new GlobalMessageRegistry();
        }
        return GlobalMessageRegistry.instance;
    }

    register(handler: RegisteredHandler): void {
        const key = `${handler.port}:${handler.opCode}`;
        const existing = this.handlers.get(key);

        if (existing) {
            throw new Error(
                `Duplicate handler for ${key}: ` +
                `existing="${existing.name}" (${existing.service}), ` +
                `new="${handler.name}" (${handler.service})`
            );
        }

        this.handlers.set(key, handler);
    }

    listAll(): RegisteredHandler[] {
        return Array.from(this.handlers.values());
    }

    getByPort(port: number): RegisteredHandler[] {
        return this.listAll().filter(h => h.port === port);
    }
    
    // For debugging/documentation
    printRegistry(): void {
        console.table(this.listAll());
    }
}

Benefits

  • Conflict detection: Duplicate registrations fail fast at startup
  • Discoverability: Single place to see all handlers
  • Debugging: Easy to print full registry for troubleshooting
  • Documentation: Can auto-generate handler documentation

Tasks

  • Create GlobalMessageRegistry class
  • Integrate with existing MessageHandlerRegistry classes
  • Add startup validation that logs all registered handlers
  • Add tests for conflict detection
  • Consider adding CLI command to list all handlers

Dependencies

Related

Part of the packet architecture improvement initiative. See PR #2801 for context.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions