Skip to content

mindwingx/golang-practical-http-grpc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GopherNet: Golang Practical Backend over HTTP and gRPC

By: Milad Roudgarian


✅ Overview

GopherNet is a backend service built to manage the rental and lifecycle of gopher burrows in a structured, scalable, and concurrent environment. The system simulates a digital platform where gophers can "rent" underground burrows, each of which evolves over time.

Each burrow has:

  • A depth that increases over time (only when rented)
  • A fixed width
  • A lifespan of 25 days
  • One renter allowed per burrow (no sharing)

The system keeps burrow status up to date and allows gophers to rent available ones. It also runs background tasks every minute to update burrow depth and age.

⚙️ Technologies Used

  • Go – Core programming language
  • Gin – REST API framework
  • gRPC – Internal service communication
  • Swagger (Go Swag) – Auto-generated API documentation
  • Hexagonal Architecture – Clean separation of core logic and infrastructure
  • Zap – Fast and structured logging
  • Goroutines + Worker Pool – Concurrency pattern for efficient background processing
  • File I/O – JSON used for input data, text files for periodic reports
  • PostgreSQL – Primary relational database for storing burrow data
  • GORM – ORM for Database integration
  • Redis – In-memory store for fast access to burrow state or caching
  • Docker – Containerized deployment
  • Docker Compose – Orchestration for multi-service setup (API, DB, Redis, etc.)

♻️ Reporting

Every 10 minutes, GopherNet generates a report showing:

  • Total combined depth
  • Number of available burrows
  • Largest and smallest burrows by volume

Reports are saved as plain text files.

🧪 Graceful Shutdown

On termination, the server stops background tasks, flushes logs, and exits cleanly.


Quick Start

  • To start service by Docker Compose
make up

Note: wait a few seconds for all Docker Compose services to be up

  • The swagger address to access APIs:

http://localhost:8080/public/swagger/index.html

The required Username and Password:

Username: admin
Password: admin
  • All the LOG files and the reports(txt files) are available in current path in ./docker directory.

System Overview

The assessment implemented as mono-repo with two microservices.

Scheduler Service

  • Startup Tasks:

    • Loads initial data from data/initial.json as seeder
    • Executes database migrations
  • CronJobs

    • Updates (runs every minute):
      • Dug depth
      • Burrow age states
      • Collapsed burrows status
    • Reports(runs every 10 minutes):
      • Generates and exports insights report (report.txt)
  • gRPC Server

    • implemented the unary call that retrive latest report and parse its text and send as response to the gRPC client.

API Service

  • Startup Tasks:
    • Many APIs implemented to handle items below:

      • Create new Burrow
      • Rent the free Burrow by the User
      • Vacate the Burrow
      • Show the Burrows list (some filters available by query params)
      • Show the Burrow info
      • Show the last available report(generated by Scheduler) via gRPC

Description

  • All the Burrows' lifetimes(age), occupancy, and collapse are evaluated by Redis TTL in both services.
  • If a burrow is vacated, the depth calculation will be paused, and it will be continued at the next rent.
  • Each Burrow is allocated to only one User. Also, each User can only rent one Burrow.
  • The CronJobs are handled by Goroutine Scheduler based on the worker pool. It is evaluated as :
    • Worker pool pattern with configurable concurrency (workers parameter)
    • Thread-safe task management using mutex (sync.Mutex)
    • Wait group (sync.WaitGroup) for task completion tracking
    • Buffered channel for task distribution
    • Auto-cleanup of completed tasks

Local Setup

To run the services locally, follow these steps:

  1. Disable the Docker app configuration:

    • Comment out the - docker/app.yml line in docker-compose.yml.
  2. Start Docker containers:

    • Run the following command to bring up the Docker environment:
      make up
  3. Handle desired directories:

    • Run the following command to catch probable missed directories:
      mkdir -p ./api/{docs,logs} && mkdir -p ./scheduler/{assets/reports,logs}
  4. Prepare environment files:

    • Generate .env files for both services:
      cd ./api/ && make env && cd ./../scheduler && make env && cd ..
    • In both services, modify the APP_DEBUG:
      APP_DEBUG=true
      
  5. Generate gRPC protobuf files:

    • In both services, execute:
      cd ./api/ && make proto && cd ./../scheduler && make proto && cd ..
  6. Install Go dependencies:

    • In both services, run:
      cd ./api/ && go mod tidy && cd ./../scheduler && go mod tidy && cd ..
  7. Generate Swagger documentation (API service only):

    • Run the following in the API service:
      cd ./api/ && make swag && cd ..
  8. Run the services:

    • Start each service manually:
      go run ./cmd/main.go

      Note: Start the Scheduler service before the API service.


Health Check CURL

To be used as the Kubernetes livenessProbe of deployment

curl -v 0.0.0.0:8080/handshake

Result

*   Trying 0.0.0.0:8080...
* Connected to 0.0.0.0 (0.0.0.0) port 8080
> GET /handshake HTTP/1.1
> Host: 0.0.0.0:8080
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With
< Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, UPDATE
< Access-Control-Allow-Origin: *
< Access-Control-Max-Age: 21600
< Content-Type: application/json; charset=utf-8
< Date: Mon, 26 May 2025 15:17:19 GMT
< Content-Length: 84
< 
* Connection #0 to host 0.0.0.0 left intact
{"status":"OK","message":"connection established","timestamp":"2025-05-26 15:17:19"}

or

{
  "status": "OK",
  "message": "connection established",
  "timestamp": "2025-05-26 15:16:14"
}

Note: Logs handled with the zap-logger and contains both stdout and log file cores.


About

GopherNet is a Golang backend service built to manage the rental and lifecycle of gopher burrows in a structured, scalable, and concurrent environment.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors