A simple distributed system implementation with a master-worker architecture using gRPC for communication between nodes.
This project implements a basic distributed system with two types of nodes:
- Master Node: Coordinates tasks and distributes them to worker nodes
- Worker Node: Executes tasks received from the master node
The system uses gRPC for communication between nodes and provides a REST API to submit tasks to the master.
- 
Master Node: - Listens for gRPC connections from worker nodes
- Provides an HTTP API for task submission
- Distributes tasks to connected worker nodes using round-robin load balancing
 
- 
Worker Node: - Connects to the master via gRPC
- Receives and executes tasks (commands)
- Reports status back to the master
- Supports unique worker IDs and configurable master address
 
- Go 1.18 or later
- protoc (Protocol Buffers compiler)
# Clone the repository
git clone https://github.com/DjonatanS/go-distributed-data-system.git
cd go-distributed-data-system
# Install dependencies
go mod tidyO arquivo principal agora está em cmd/server/main.go e o exemplo de cluster/demo está em example/cluster_demo/main.go.
# Usando argumentos por flag
go run cmd/server/main.go -type=master
# Para compatibilidade antiga (se aplicável)
go run cmd/server/main.go masterIsso irá iniciar:
- Um servidor gRPC na porta 50051 para conexões de workers
- Uma API REST na porta 9092 para submissão de tarefas
# Usando argumentos por flag com ID customizado
go run cmd/server/main.go -type=worker -id=worker1 -master=localhost:50051
# Para compatibilidade antiga (se aplicável)
go run cmd/server/main.go worker# Inicia um master e 3 workers (padrão)
go run cmd/server/main.go -type=cluster
# Inicia um master com 5 workers
go run cmd/server/main.go -type=cluster -workers=5Execute o exemplo de cluster/demo, que inicia o cluster e envia tarefas automaticamente:
go run example/cluster_demo/main.goVocê pode submeter tarefas para o master usando a API REST:
curl -X POST http://localhost:9092/tasks \
  -H "Content-Type: application/json" \
  -d '{"cmd":"echo hello world"}'| Endpoint | Method | Description | 
|---|---|---|
| /tasks | POST | Submit a task to be executed by worker nodes. Request body: {"cmd":"command_to_execute"} | 
| /workers | GET | Get count of currently connected workers | 
The system defines the following gRPC services:
service NodeService {
    rpc ReportStatus(Request) returns (Response){};
    rpc AssignTask(Request) returns (stream Response){};
}- 
Initialization: - The master node starts and listens for gRPC connections
- Worker nodes connect to the master via gRPC and register themselves
 
- 
Task Assignment: - Tasks are submitted via HTTP to the master's REST API
- The master distributes tasks to workers using round-robin load balancing
- Each task is sent to exactly one worker
 
- 
Command Execution: - Workers receive commands and execute them using the system's shell
- The execution output is captured and printed on the worker's console
- Workers automatically reconnect if the connection to the master is lost
 
.
├── cmd/
│   └── server/
│       └── main.go         # Entry point principal (CLI)
├── core/
│   ├── node.go             # Master node and service implementations
│   ├── node.pb.go          # Generated protobuf message definitions
│   ├── node_grpc.pb.go     # Generated gRPC service definitions
│   ├── node.proto          # Protocol buffer definitions
│   ├── worker_node.go      # Worker node implementation
│   ├── node_test.go        # Unit tests for the master node
│   └── worker_node_test.go # Unit tests for the worker node
├── example/
│   └── cluster_demo/
│       └── main.go         # Exemplo de uso programático do cluster
├── launcher/
│   ├── launcher.go         # Package to start both master and workers together
│   └── launcher_test.go    # Tests for the launcher package
├── go.mod
├── go.sum
└── README.md
The master node:
- Creates a gRPC server for worker connections
- Maintains a thread-safe registry of connected workers
- Provides a REST API for task submission (using Gin)
- Distributes commands to workers using round-robin load balancing
- Monitors worker connections and removes disconnected workers
The worker node:
- Establishes a gRPC connection to the master
- Has configurable parameters (ID, master address, reconnect delay)
- Creates a streaming connection for receiving tasks
- Executes commands using Go's execpackage and captures output
- Handles reconnection to the master if the connection is lost
- Reports status to the master with its worker ID
The launcher package provides:
- A simple way to start both master and multiple workers from a single import
- Configurable number of workers and other settings
- Clean shutdown handling with proper context cancellation
- Client submits a task to master's REST API
- Master selects a worker using round-robin and sends the task via gRPC stream
- Worker executes the command and displays the output
- If a worker disconnects, the master removes it from the pool
You can also use the launcher package to programmatically start a cluster:
import "github.com/DjonatanS/go-distribuited-data-system/launcher"
// Start a cluster with default configuration (1 master + 3 workers)
cluster := launcher.StartCluster()
// Or customize the configuration
config := launcher.DefaultClusterConfig()
config.WorkerCount = 5
cluster := launcher.NewCluster(config)
cluster.Start()
// Later, when finished
cluster.Stop()type WorkerConfig struct {
    ID             string        // Worker identifier
    MasterAddr     string        // Address of the master node (host:port)
    ReconnectDelay time.Duration // Delay between reconnection attempts
}type ClusterConfig struct {
    MasterPort     int           // Port for the master's gRPC server (default: 50051)
    ApiPort        int           // Port for the master's REST API (default: 9092)
    WorkerCount    int           // Number of workers to start (default: 3)
    MasterHost     string        // Host for the master node (default: "localhost")
    BaseWorkerID   string        // Base prefix for worker IDs (default: "worker")
    ReconnectDelay time.Duration // Delay between worker reconnection attempts (default: 5s)
}The system includes both unit and integration tests:
# Run all tests
go test ./...
# Run unit tests only
go test ./core -run "^Test[^Integration]"If you modify the .proto files, regenerate the Go code:
protoc --go_out=. --go_opt=paths=source_relative \
    --go-grpc_out=. --go-grpc_opt=paths=source_relative \
    core/node.proto- More advanced task scheduling and prioritization
- Worker capabilities registration and task routing based on capabilities
- Authentication and security measures
- Better error handling and retry mechanisms
- Persistence of tasks and results
- Web-based administrative UI
[License information]