Machine Coding Problem

Discord / Slack (Messaging)

maco60macoAllmessagingsession-managementpub-sub
Commonly Asked By:DiscordSlackMetaMicrosoft

Requirements & System Scope

Functional Scope (In-Scope)

  • Real-time Message Broker (Pub-Sub): Publish messages to channels and broadcast them to connected subscribers instantly.
  • Workspace & Channel Trees: Organise groups, public channels, private channels, and direct messages (DMs).
  • Session Management: Map active browser or device socket handles to online users.
  • Read Receipt Tracker: Keep track of the last read message ID per user per channel dynamically.

Explicit Boundaries (Out-of-Scope)

  • No Native Audio/Video WebRTC Media Sockets: Bypasses live video codecs, WebRTC STUN/TURN connection routes, or audio echo cancellation filters.
  • No Automatic Link Previews: Does not scrape external HTML pages to parse Open Graph metadata cards in real time.

Class Diagram & Entity Relationships

Structural layout showing relationships between messaging workspaces, channels, sessions, and pub-sub topics:

Loading...
  • Polymorphic Channels: Channel manages message history logs and active subscriber connections.
  • Active Session Handlers: Session links socket endpoints to specific user profiles to push incoming payloads.

Design Patterns & SOLID Principles

  • Observer Pattern (Channel Pub-Sub): Decoupling publishers (users posting messages) from observers (connected subscriber client sessions) enables instant message delivery, satisfying Open-Closed Principle.
  • Single Responsibility Principle (SRP):Channel handles message lists and notifications; SessionManager tracks online status; PresenceService manages heartbeat monitors.

Core Execution Workflows

Message Transmission & Fan-Out

  1. Rider publishes message: sendMessage(userId, channelId, text).
  2. Assign sequential ID number to message to guarantee ordering.
  3. Write message to persistent history logs in database.
  4. Fetch active subscriber connections from SessionManager.
  5. Iterate and deliver payloads concurrently:
    1. If the subscriber is online, push the message through their active session connection.
    2. If offline, queue the message in the notification service database for later delivery.

Concurrency & Thread Safety Strategy

When thousands of users post, subscribe, and query presence statuses concurrently across large channels:

  • Copy-On-Write Message History: Use thread-safe historical lists (e.g., CopyOnWriteArrayList) to allow seamless reads while messages are appended.
  • Asynchronous Fan-out Executors: Offload message broadcasts for large channels (10,000+ members) to asynchronous background threads to avoid blocking the main API thread.

Complete Clean Code Blueprint

Clean reference designs demonstrating pub-sub channels in Java and Python:

// โ”€โ”€โ”€ JAVA BLUEPRINT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
import java.util.*;
import java.util.concurrent.*;

enum UserPresence {
    ONLINE, AWAY, DND, OFFLINE
}

class User {
    private final String userId;
    private final String username;

    public User(String userId, String username) {
        this.userId = userId;
        this.username = username;
    }

    public String getUserId() { return userId; }
    public String getUsername() { return username; }
}

class Message {
    private final String id;
    private final String senderId;
    private final String channelId;
    private final String content;
    private final long timestamp;

    public Message(String id, String senderId, String channelId, String content) {
        this.id = id;
        this.senderId = senderId;
        this.channelId = channelId;
        this.content = content;
        this.timestamp = System.currentTimeMillis();
    }

    public String getId() { return id; }
    public String getSenderId() { return senderId; }
    public String getChannelId() { return channelId; }
    public String getContent() { return content; }
    public long getTimestamp() { return timestamp; }
}

interface MessageSubscriber {
    void onMessage(Message msg);
    String getUserId();
}

class UserSession implements MessageSubscriber {
    private final String sessionId;
    private final String userId;

    public UserSession(String sessionId, String userId) {
        this.sessionId = sessionId;
        this.userId = userId;
    }

    @Override
    public void onMessage(Message msg) {
        System.out.println("[Session " + sessionId + " | User " + userId + "] Received Live Message in Channel " 
                           + msg.getChannelId() + " from " + msg.getSenderId() + ": " + msg.getContent());
    }

    @Override
    public String getUserId() { return userId; }
}

class Channel {
    private final String channelId;
    private final String name;
    private final List<Message> history = new CopyOnWriteArrayList<>();
    private final Set<MessageSubscriber> activeSubscribers = ConcurrentHashMap.newKeySet();

    public Channel(String channelId, String name) {
        this.channelId = channelId;
        this.name = name;
    }

    public String getChannelId() { return channelId; }
    public String getName() { return name; }

    public void subscribe(MessageSubscriber sub) {
        activeSubscribers.add(sub);
    }

    public void unsubscribe(MessageSubscriber sub) {
        activeSubscribers.remove(sub);
    }

    public void publish(Message msg) {
        history.add(msg);
        for (MessageSubscriber sub : activeSubscribers) {
            sub.onMessage(msg);
        }
    }

    public List<Message> getHistory() { return new ArrayList<>(history); }
}

class Workspace {
    private final String id;
    private final String name;
    private final Map<String, Channel> channels = new ConcurrentHashMap<>();
    private final Set<String> members = ConcurrentHashMap.newKeySet();

    public Workspace(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() { return id; }
    public void addChannel(Channel ch) { channels.put(ch.getChannelId(), ch); }
    public Channel getChannel(String chId) { return channels.get(chId); }
    public void addMember(String userId) { members.add(userId); }
    public boolean hasMember(String userId) { return members.contains(userId); }
}

class PresenceManager {
    private final Map<String, UserPresence> presenceMap = new ConcurrentHashMap<>();
    private final Map<String, Set<String>> presenceWatchers = new ConcurrentHashMap<>();

    public void setPresence(String userId, UserPresence presence) {
        presenceMap.put(userId, presence);
        System.out.println("Presence alert: User " + userId + " is now " + presence);
        Set<String> watchers = presenceWatchers.get(userId);
        if (watchers != null) {
            for (String watcher : watchers) {
                System.out.println("-> Notified " + watcher + " about User " + userId + "'s presence status: " + presence);
            }
        }
    }

    public UserPresence getPresence(String userId) {
        return presenceMap.getOrDefault(userId, UserPresence.OFFLINE);
    }

    public void watchPresence(String watcherUserId, String targetUserId) {
        presenceWatchers.computeIfAbsent(targetUserId, k -> ConcurrentHashMap.newKeySet()).add(watcherUserId);
    }
}

class ReadReceiptTracker {
    // Map of UserID -> (ChannelID -> LastReadMessageID)
    private final Map<String, Map<String, String>> readReceipts = new ConcurrentHashMap<>();

    public void markAsRead(String userId, String channelId, String messageId) {
        readReceipts.computeIfAbsent(userId, k -> new ConcurrentHashMap<>()).put(channelId, messageId);
        System.out.println("User " + userId + " read up to message: " + messageId + " in channel " + channelId);
    }

    public String getLastReadMessage(String userId, String channelId) {
        Map<String, String> userReceipts = readReceipts.get(userId);
        return userReceipts != null ? userReceipts.get(channelId) : null;
    }
}

class MessagingService {
    private final Map<String, Workspace> workspaceRegistry = new ConcurrentHashMap<>();
    private final Map<String, UserSession> activeSessions = new ConcurrentHashMap<>();
    private final PresenceManager presenceManager = new PresenceManager();
    private final ReadReceiptTracker readReceiptTracker = new ReadReceiptTracker();

    public void registerWorkspace(Workspace ws) {
        workspaceRegistry.put(ws.getId(), ws);
    }

    public Workspace getWorkspace(String wsId) { return workspaceRegistry.get(wsId); }

    public void userLogin(String userId, String sessionId) {
        UserSession session = new UserSession(sessionId, userId);
        activeSessions.put(userId, session);
        presenceManager.setPresence(userId, UserPresence.ONLINE);

        // Auto-subscribe to all workspace channels the user belongs to
        for (Workspace ws : workspaceRegistry.values()) {
            if (ws.hasMember(userId)) {
                for (Channel ch : ws.channels.values()) {
                    ch.subscribe(session);
                }
            }
        }
    }

    public void userLogout(String userId) {
        UserSession session = activeSessions.remove(userId);
        presenceManager.setPresence(userId, UserPresence.OFFLINE);
        if (session != null) {
            for (Workspace ws : workspaceRegistry.values()) {
                for (Channel ch : ws.channels.values()) {
                    ch.unsubscribe(session);
                }
            }
        }
    }

    public void postMessage(String wsId, String chId, String senderId, String text) {
        Workspace ws = getWorkspace(wsId);
        if (ws == null || !ws.hasMember(senderId)) {
            System.out.println("Sender " + senderId + " is not a member of Workspace " + wsId);
            return;
        }

        Channel channel = ws.getChannel(chId);
        if (channel == null) {
            System.out.println("Channel " + chId + " does not exist in workspace.");
            return;
        }

        String msgId = UUID.randomUUID().toString().substring(0, 8);
        Message message = new Message(msgId, senderId, chId, text);
        channel.publish(message);

        // Auto-mark as read for sender
        readReceiptTracker.markAsRead(senderId, chId, msgId);
    }

    public PresenceManager getPresenceManager() { return presenceManager; }
    public ReadReceiptTracker getReadReceiptTracker() { return readReceiptTracker; }
}

public class Main {
    public static void main(String[] args) {
        MessagingService service = new MessagingService();

        // 1. Create Workspace & Channels
        Workspace ws = new Workspace("W-TECH", "TechCorp");
        Channel devChannel = new Channel("C-DEV", "development");
        Channel randomChannel = new Channel("C-RANDOM", "random");
        ws.addChannel(devChannel);
        ws.addChannel(randomChannel);

        ws.addMember("U-Alice");
        ws.addMember("U-Bob");
        service.registerWorkspace(ws);

        // 2. Setup Presence Monitoring
        service.getPresenceManager().watchPresence("U-Alice", "U-Bob");

        // 3. User Login & Auto Subscriptions
        System.out.println("--- Users logging in ---");
        service.userLogin("U-Alice", "S-ALICE-101");
        service.userLogin("U-Bob", "S-BOB-202");

        // 4. Send Message & Verify Fanout
        System.out.println("\n--- Sending channel message ---");
        service.postMessage("W-TECH", "C-DEV", "U-Alice", "Hey Bob, did you review the PR?");

        // 5. Check Presence Changes
        System.out.println("\n--- Simulating status update ---");
        service.getPresenceManager().setPresence("U-Bob", UserPresence.AWAY);

        // 6. User logout and verify unsubscribe
        System.out.println("\n--- Bob logging out ---");
        service.userLogout("U-Bob");

        System.out.println("\n--- Alice posting after Bob logged out ---");
        service.postMessage("W-TECH", "C-DEV", "U-Alice", "I'll merge it then!");
    }
}

๐Ÿ’ฌReview

Help Us Improve

How helpful was this walkthrough?

Click a star to rate. We actively use this feedback to refine and update our system design content.

Placeholder
Optional but highly appreciated!

Discussion

Share your thoughts, ask questions, or help others.

Loading comments...