Last spring I helped a small guesthouse in Göreme keep its booking calendar straight. They take reservations through two channels: a web form that writes to a SQLite file, and walk-in bookings typed into the same file by whoever is at the desk. Both happened at once maybe a dozen times a day in high season. After a week I saw double-booked rooms and one case where a cancel erased a newer booking. The database was a 3 MB file, nothing exotic.
My first fix was boring: put bookings in a queue and process them one at a time. I wrote a small Python service with a single worker and a UNIX socket. The form posts JSON to it, the desk terminal uses the same call. A reservation becomes a row only after the worker checks overlapping dates and room inventory.
import sqlite3, json, socketserver
def reserve(conn, room, start, end, name):
cur = conn.execute(
'SELECT COUNT(*) FROM bookings '
'WHERE room=? AND NOT (end<=? OR start>=?)',
(room, start, end))
if cur.fetchone()[0]:
return {'ok': False, 'reason': 'overlap'}
conn.execute(
'INSERT INTO bookings(room,start,end,name) VALUES (?,?,?,?)',
(room, start, end, name))
conn.commit()
return {'ok': True}
The worker serialized writes, so the race was gone. What it did not fix was the desk browser submitting twice when the connection dropped. I added a client-generated request id and a UNIQUE constraint on it. That stopped the duplicate rows.
Why this shape: a single writer is easy to reason about and easy to audit. The cost is throughput, but a dozen bookings a day do not care. The bigger cost is that the worker is a single point of failure. When it crashed once on a malformed date, the form silently failed and the owner thought bookings were lost. I moved logs to a file the desk can read and made failures visible in the browser.
Where it breaks: if a second guesthouse is added, one process handling both calendars will still serialize everything, which is fine until it is not. Also, my overlap check assumes checkout day can be a check-in day, which is true here but would be wrong for properties that need cleaning time between guests. I ran into that at a different place and had to add a buffer column.
If you run something similar for a small business, how do you make a failed write obvious to someone who is not going to read a log file?
0 条评论
还没有评论,写下第一条。