Add global notes/links overview modals and fix SSE drain race condition
This commit is contained in:
73
app/app.py
73
app/app.py
@@ -240,12 +240,6 @@ def collect_all():
|
||||
|
||||
# Update database (all in main collector thread)
|
||||
with app.app_context():
|
||||
# Remove servers no longer in config
|
||||
config_keys = {(e['username'], e['hostname']) for e in entries}
|
||||
for server in Server.query.all():
|
||||
if (server.username, server.hostname) not in config_keys:
|
||||
db.session.delete(server)
|
||||
|
||||
for key, (entry, result) in results.items():
|
||||
server = Server.query.filter_by(
|
||||
username=entry['username'],
|
||||
@@ -289,12 +283,23 @@ def collector_loop():
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
# Get group order from config file and filter to configured servers only
|
||||
config_entries = parse_infrastructure_conf()
|
||||
config_keys = {(e['username'], e['hostname']) for e in config_entries}
|
||||
group_order = []
|
||||
for e in config_entries:
|
||||
g = e['group']
|
||||
if g not in group_order:
|
||||
group_order.append(g)
|
||||
|
||||
all_servers = Server.query.order_by(Server.group_name, Server.primary_ip).all()
|
||||
|
||||
# Separate parents and children
|
||||
# Separate parents and children (only servers in current config)
|
||||
children_map = {} # parent_hostname -> [child_servers]
|
||||
parents = []
|
||||
for s in all_servers:
|
||||
if (s.username, s.hostname) not in config_keys:
|
||||
continue
|
||||
if s.parent_hostname:
|
||||
children_map.setdefault(s.parent_hostname, []).append(s)
|
||||
else:
|
||||
@@ -304,14 +309,6 @@ def index():
|
||||
for hostname in children_map:
|
||||
children_map[hostname].sort(key=lambda s: _ip_sort_key(s.primary_ip))
|
||||
|
||||
# Get group order from config file
|
||||
config_entries = parse_infrastructure_conf()
|
||||
group_order = []
|
||||
for e in config_entries:
|
||||
g = e['group']
|
||||
if g not in group_order:
|
||||
group_order.append(g)
|
||||
|
||||
# Group parents, preserving config order
|
||||
groups = {}
|
||||
for s in parents:
|
||||
@@ -430,11 +427,6 @@ def api_refresh_stream():
|
||||
|
||||
# Update database
|
||||
with app.app_context():
|
||||
config_keys = {(e['username'], e['hostname']) for e in entries}
|
||||
for server in Server.query.all():
|
||||
if (server.username, server.hostname) not in config_keys:
|
||||
db.session.delete(server)
|
||||
|
||||
for key, (entry, result) in results.items():
|
||||
server = Server.query.filter_by(
|
||||
username=entry['username'], hostname=entry['hostname'],
|
||||
@@ -530,19 +522,19 @@ def api_refresh_one_stream(server_id):
|
||||
t.start()
|
||||
|
||||
# Stream progress while collecting
|
||||
while not host_done.is_set():
|
||||
result = None
|
||||
while not host_done.is_set() or not progress_q.empty():
|
||||
try:
|
||||
kind, val = progress_q.get(timeout=0.3)
|
||||
if kind == 'progress':
|
||||
yield f"data: {val}\n\n"
|
||||
elif kind == 'result':
|
||||
break
|
||||
result = val
|
||||
except _queue.Empty:
|
||||
continue
|
||||
|
||||
t.join()
|
||||
# Drain remaining messages
|
||||
result = None
|
||||
# Drain anything remaining
|
||||
while not progress_q.empty():
|
||||
kind, val = progress_q.get_nowait()
|
||||
if kind == 'progress':
|
||||
@@ -592,18 +584,18 @@ def api_refresh_one_stream(server_id):
|
||||
ct = threading.Thread(target=_collect_child)
|
||||
ct.start()
|
||||
|
||||
while not child_done.is_set():
|
||||
child_result = None
|
||||
while not child_done.is_set() or not child_q.empty():
|
||||
try:
|
||||
kind, val = child_q.get(timeout=0.3)
|
||||
if kind == 'progress':
|
||||
yield f"data: {val}\n\n"
|
||||
elif kind == 'result':
|
||||
break
|
||||
child_result = val
|
||||
except _queue.Empty:
|
||||
continue
|
||||
|
||||
ct.join()
|
||||
child_result = None
|
||||
while not child_q.empty():
|
||||
kind, val = child_q.get_nowait()
|
||||
if kind == 'progress':
|
||||
@@ -655,6 +647,33 @@ def api_update_links(server_id):
|
||||
return jsonify({'ok': True})
|
||||
|
||||
|
||||
@app.route('/api/all-notes')
|
||||
def api_all_notes():
|
||||
servers = Server.query.filter(Server.notes != '', Server.notes != None).all()
|
||||
return jsonify([{
|
||||
'id': s.id,
|
||||
'hostname': s.hostname,
|
||||
'group_name': s.group_name,
|
||||
'notes': s.notes,
|
||||
} for s in servers])
|
||||
|
||||
|
||||
@app.route('/api/all-links')
|
||||
def api_all_links():
|
||||
servers = Server.query.filter(Server.links != None, Server.links != '[]').all()
|
||||
result = []
|
||||
for s in servers:
|
||||
links = s.links or []
|
||||
if links:
|
||||
result.append({
|
||||
'id': s.id,
|
||||
'hostname': s.hostname,
|
||||
'group_name': s.group_name,
|
||||
'links': links,
|
||||
})
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
def _ip_sort_key(ip_str):
|
||||
if not ip_str:
|
||||
return [999, 999, 999, 999]
|
||||
|
||||
Reference in New Issue
Block a user