30 lines
1,009 B
Python
30 lines
1,009 B
Python
"""Persistent one-run target-timeout budget; every reservation is durable."""
|
|
import fcntl
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
|
|
LIMITS = {'run': 1, 'episode': 1, 'camera': 1, 'capture': 12}
|
|
|
|
|
|
def reserve(lab: Path, resource: str) -> dict:
|
|
if resource not in LIMITS:
|
|
raise ValueError('unknown budget resource')
|
|
path = lab / 'timeout-budget.json'
|
|
with path.open('a+') as file:
|
|
fcntl.flock(file, fcntl.LOCK_EX)
|
|
file.seek(0)
|
|
raw = file.read()
|
|
state = json.loads(raw) if raw else {key: 0 for key in LIMITS}
|
|
if state[resource] >= LIMITS[resource]:
|
|
raise RuntimeError(f'{resource} budget exhausted')
|
|
if resource != 'run' and state['run'] != 1:
|
|
raise RuntimeError('run must be reserved first')
|
|
state[resource] += 1
|
|
file.seek(0)
|
|
file.truncate()
|
|
json.dump(state, file, sort_keys=True)
|
|
file.write('\n')
|
|
file.flush()
|
|
os.fsync(file.fileno())
|
|
return state
|