Implement HTTP timeout configurations and enhance API documentation

- Added optional HTTP server timeout configurations (`HNHMAP_READ_TIMEOUT`, `HNHMAP_WRITE_TIMEOUT`, `HNHMAP_IDLE_TIMEOUT`) to `.env.example` and updated the server initialization in `main.go` to utilize these settings.
- Enhanced API documentation for the `rebuildZooms` endpoint to clarify its background processing and polling mechanism for status updates.
- Updated `configuration.md` to include new timeout environment variables for better configuration guidance.
- Improved error handling in the client for large request bodies, ensuring appropriate responses for oversized payloads.
This commit is contained in:
2026-03-04 11:59:28 +03:00
parent a3a4c0e896
commit dda35baeca
17 changed files with 396 additions and 73 deletions

View File

@@ -17,7 +17,9 @@ func New(db *bbolt.DB) *Store {
return &Store{db: db}
}
// View runs fn in a read-only transaction. Checks context before starting.
// View runs fn in a read-only transaction. It checks context before starting.
// Long-running callbacks (e.g. large ForEach or ForEachTile) should check ctx.Done()
// periodically and return ctx.Err() to abort early when the context is cancelled.
func (s *Store) View(ctx context.Context, fn func(tx *bbolt.Tx) error) error {
select {
case <-ctx.Done():
@@ -27,7 +29,8 @@ func (s *Store) View(ctx context.Context, fn func(tx *bbolt.Tx) error) error {
}
}
// Update runs fn in a read-write transaction. Checks context before starting.
// Update runs fn in a read-write transaction. It checks context before starting.
// Long-running callbacks should check ctx.Done() periodically and return ctx.Err() to abort.
func (s *Store) Update(ctx context.Context, fn func(tx *bbolt.Tx) error) error {
select {
case <-ctx.Done():
@@ -284,6 +287,30 @@ func (s *Store) GetTile(tx *bbolt.Tx, mapID, zoom int, coordKey string) []byte {
return zoomB.Get([]byte(coordKey))
}
// GetTiles returns raw JSON for multiple tiles in the same map/zoom in one transaction.
// Keys that are not found are omitted from the result. Coord keys are in the form "x_y".
func (s *Store) GetTiles(tx *bbolt.Tx, mapID, zoom int, coordKeys []string) map[string][]byte {
out := make(map[string][]byte, len(coordKeys))
tiles := tx.Bucket(BucketTiles)
if tiles == nil {
return out
}
mapB := tiles.Bucket([]byte(strconv.Itoa(mapID)))
if mapB == nil {
return out
}
zoomB := mapB.Bucket([]byte(strconv.Itoa(zoom)))
if zoomB == nil {
return out
}
for _, k := range coordKeys {
if v := zoomB.Get([]byte(k)); v != nil {
out[k] = v
}
}
return out
}
// PutTile stores a tile entry (creates nested buckets as needed).
func (s *Store) PutTile(tx *bbolt.Tx, mapID, zoom int, coordKey string, raw []byte) error {
tiles, err := tx.CreateBucketIfNotExists(BucketTiles)