Skip to content

Latest commit

 

History

History
280 lines (233 loc) · 8.99 KB

ARCHITECTURE.md

File metadata and controls

280 lines (233 loc) · 8.99 KB

Architecture Documentation

System Overview

This project implements Conway's Game of Life using a multi-process architecture with Inter-Process Communication (IPC).

Architecture Diagram

┌─────────────────────────────────────────────────────────────┐
│                        Browser (Angular)                     │
│  ┌──────────────────┐              ┌──────────────────┐    │
│  │  Draw Canvas     │              │ Simulation View   │    │
│  │  (Left Panel)    │              │  (Right Panel)    │    │
│  └──────────────────┘              └──────────────────┘    │
│           │                                   │              │
│           └────────────┬──────────────────────┘              │
│                        │ HTTP REST API                       │
└────────────────────────┼─────────────────────────────────────┘
                         │
                         ▼
            ┌────────────────────────┐
            │   HTTP Server (C)      │
            │   Port 8081            │
            └────────────┬───────────┘
                         │
                         ▼
            ┌────────────────────────┐
            │   Grid Manager (C)     │
            │   - fork() cells       │
            │   - coordinate IPC     │
            └────────────┬───────────┘
                         │
         ┌───────────────┼───────────────┐
         │               │               │
         ▼               ▼               ▼
    ┌────────┐      ┌────────┐      ┌────────┐
    │Cell[0,0]│      │Cell[0,1]│ ... │Cell[n,n]│
    │ Process │      │ Process │     │ Process │
    │  (fork) │      │  (fork) │     │  (fork) │
    └────┬────┘      └────┬────┘     └────┬────┘
         │                │               │
         │    pipe()      │    pipe()     │
         └────────────────┴───────────────┘
              Bidirectional Communication

Components

1. Angular Frontend (src/app/)

DrawCanvasComponent

  • Interactive drawing canvas
  • 20x20 grid for pattern creation
  • Click and drag to draw
  • Toggle between draw/erase modes

SimulationViewComponent

  • Displays live simulation
  • Shows generation count
  • Displays number of alive cells
  • Highlights all processes (alive and dead)

ConwayService

  • HTTP client for API communication
  • Handles state queries, cell updates, and ticks
  • Provides auto-tick observable for animation

AppComponent

  • Main orchestration component
  • Controls simulation start/stop/step/reset
  • Manages timing and coordination

2. C Backend (backend/src/)

cell.c / cell.h

  • Cell process implementation
  • Runs in its own forked process
  • Maintains cell state (alive/dead)
  • Handles IPC messages
  • Implements Conway's rules

grid.c / grid.h

  • Grid manager
  • Spawns cell processes using fork()
  • Creates pipe pairs for each cell
  • Coordinates generation ticks
  • Collects and distributes cell states

server.c / server.h

  • HTTP REST API server
  • Socket-based implementation
  • Handles GET/POST requests
  • CORS support for Angular dev server

main.c

  • Entry point
  • Signal handling (SIGINT/SIGTERM)
  • Cleanup and graceful shutdown

IPC Mechanism

Pipe Architecture

Each cell process has two pipes:

Parent Process                          Child Process (Cell)
     │                                        │
     │  ┌──────────────────────────┐         │
     ├──┤ pipe[1] (write_fd)       ├─────────┤── pipe[0] (read_fd)
     │  └──────────────────────────┘         │
     │       Commands (MSG_*)                 │
     │                                        │
     │  ┌──────────────────────────┐         │
     ├──┤ pipe[0] (read_fd)        ├─────────┤── pipe[1] (write_fd)
     │  └──────────────────────────┘         │
     │       Responses (state)                │

Message Types

typedef enum {
    MSG_STATE_QUERY,      // Query cell's current state
    MSG_STATE_RESPONSE,   // Response with state
    MSG_UPDATE,           // Update cell's state
    MSG_TICK,             // Compute next generation
    MSG_SHUTDOWN          // Terminate process
} MessageType;

Message Flow

Initialization:

  1. Parent forks a child process for each cell
  2. Parent keeps write_fd for commands
  3. Child keeps read_fd for receiving commands
  4. Bidirectional communication established

State Update:

Browser → HTTP → Grid Manager → pipe → Cell Process
                                      ↓
                                   Updates state

Generation Tick:

Browser → HTTP → Grid Manager
                      ↓
               Broadcast MSG_TICK to all cells
                      ↓
               Each cell queries neighbors
                      ↓
               Each cell computes next state
                      ↓
               Cells respond with new state
                      ↓
               Grid Manager collects responses
                      ↓
               Grid Manager updates all cells
                      ↓
               HTTP Response → Browser

Conway's Game of Life Rules

Implemented in cell_compute_next_state():

  1. Survival: Live cell with 2-3 neighbors → stays alive
  2. Birth: Dead cell with exactly 3 neighbors → becomes alive
  3. Death: All other cases → cell dies or stays dead
if (cell_is_alive) {
    return (neighbors == 2 || neighbors == 3);
} else {
    return (neighbors == 3);
}

API Endpoints

GET /api/state

Returns current grid state:

{
  "width": 20,
  "height": 20,
  "generation": 42,
  "cells": [
    {"x": 5, "y": 5},
    {"x": 5, "y": 6}
  ]
}

POST /api/set

Set individual cell state:

{
  "x": 10,
  "y": 10,
  "alive": 1
}

POST /api/tick

Advance one generation. Returns:

{
  "success": true,
  "generation": 43
}

POST /api/clear

Clear all cells:

{
  "success": true
}

Performance Characteristics

For 20x20 Grid:

  • Processes: 400 (1 per cell)
  • File Descriptors: 800 (2 pipes per cell)
  • Memory: ~1-2MB per process = ~400-800MB total
  • Generation Time: O(n²) where n = grid dimension

Scalability:

  • Limited by system's process/fd limits
  • Default max: 50x50 (2500 processes)
  • Can be adjusted in grid.h:
    #define MAX_GRID_SIZE 50

Build System

Makefile Targets:

  • make or make all - Build the project
  • make clean - Remove build artifacts
  • make run - Build and run server
  • make debug - Build with debug symbols

Compiler Flags:

  • -Wall -Wextra - All warnings
  • -O2 - Optimization level 2
  • -Iinclude - Include header directory
  • -lpthread - Link pthread (for future extensions)

Security Considerations

  1. No input validation: This is a demo project
  2. CORS wide open: Allows all origins
  3. No authentication: Public API
  4. Resource limits: Can spawn many processes

Note: This is a demonstration project. Production use would require proper input validation, authentication, and resource limits.

Future Enhancements

  1. Direct cell-to-cell IPC: Use SCM_RIGHTS to pass FDs between processes
  2. WebSocket support: Real-time updates instead of polling
  3. Shared memory: For faster state synchronization
  4. Thread pool: Alternative to process-per-cell
  5. Pattern library: Pre-defined patterns (glider, blinker, etc.)
  6. Grid resizing: Dynamic grid size changes
  7. Performance metrics: Process stats, IPC latency

References