Evento is a proof of concept (POC) for a highly concurrent room reservation system built with Go and PostgreSQL. It simulates multiple clients and servers handling reservations for events and hotels, demonstrating and comparing different strategies for maintaining consistency under concurrent access. The project includes HTTP endpoints, a simple database schema, and configurable concurrency modes to test and validate reliable reservation handling.
The objective of this POC is to validate that a concurrently consistent system is possible using Go and Postgres. As a side product, the repo demonstrates the means required to achieve such consistency and compare different strategies to achieve it.
- Evento hosts an event with a set of rooms available at different hotels
- Multiple clients could try to reserve rooms at the same time
- At any given time there might be more than one instance of Evento running
- There is only ONE instance of the postgres database.
- Rooms are reserved concurrently by clients
- Evento should NOT allow to reserve more than the rooms available
The server is a simple HTTP server exposing two endpoints:
GET /{event_id}/available: Returns the number of available rooms for a given event and hotel.POST /{event_id}/{hotel_id}/reserve/{mode}: Reserves a number of rooms for a given event and hotel.
The client is a function trying to reserve a number of rooms for a given event and hotel. It tries to reserve rooms until it gets a response from the server saying there are no more rooms available.
- It calls
GET /{event_id}/{hotel_id}/available to check how many rooms are available - If there are rooms available, it calls
POST /{event_id}/{hotel_id}/reserve/{mode}/to try to reserve a number of rooms (1-5) - It then makes a random pause (
0-300ms) - If the reservation is successful, it repeats the process
- If the reservation fails because there are no more rooms available, it stops
- If the reservation fails because of a conflict, it retries
At any given time there might be more than one instance of the server running, simulating a distributed system.
The database is a PostgreSQL database as simple as possible, for the purpose of the POC we've kept the tables lite. At the database level we have a few tables that store the reservation data and available rooms.
- events (id, name)
- hotels (id, name)
- event_hotel_rooms (id, event_id, hotel_id, assigned, reserved, locked, updated_at)
- reservations (id, name, event_hotel_rooms_id, number)
Ensure you've cloned this repo and your current working directory is the root of it. To run Evento you need to have Go installed on your machine and a postgres database to use, either local or remote works.
Once you have the requirements, at the root folder run Evento using Go with:
> go run ./cmd/You can specify the number of concurrent clients, servers, the mode to use and the number of rooms per hotel using command parameters:
> go run ./cmd/ --clients 200 --strategy naive --rooms 200 --servers 2Where:
--clients 200specifies the number of concurrent clients to simulate,--mode naiveis the mode to use--rooms 200is the number of rooms per hotel--servers 2is the number of servers to run
The strategies available are:
- naive: No concurrency control at all
- pessimistic: Pessimistic locking using
SELECT ... FOR UPDATEfunc - atomic: Transactional approach without locking
- optimistic: Optimistic locking using
updated_attimestamp
Database connection parameters can be set using DATABASE_URL environment variable. By default it will connect to postgres://postgres@localhost:5432/evento.
- Locking rooms (part of the reservation)
- Better TUI, including progress.