Keeping a Kapadokya Guesthouse Booking Script Honest

这篇内容暂时只有 English 版本,以下是原文。

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
赞同度 100% · 0 条评论 · 1 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。