v1.0.49: in-memory tracker (no file IO); traceback on tracker error; refreshInstances adds new items; no selectService on OK
This commit is contained in:
+1
-1
@@ -6,7 +6,7 @@ from routes.main import bp as main_bp
|
||||
from routes.api import bp as api_bp
|
||||
from routes.api_test import bp as api_test_bp
|
||||
|
||||
VERSION = "1.0.48"
|
||||
VERSION = "1.0.49"
|
||||
|
||||
app = Flask(__name__, template_folder="templates", static_folder="static")
|
||||
app.config["NUBES_API_ENDPOINT"] = os.getenv("NUBES_API_ENDPOINT", "https://lk-api-gateway-dev.ngcloud.ru/api/v1/svc")
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
"""Трекер созданных инстансов — только те что породило приложение."""
|
||||
import json
|
||||
import os
|
||||
"""Трекер созданных инстансов — in-memory dict (один gunicorn worker)."""
|
||||
import threading
|
||||
|
||||
_LOCK = threading.Lock()
|
||||
_PATH = "/tmp/instances.json"
|
||||
|
||||
_INITIAL = {
|
||||
_data = {
|
||||
"408b7f96-6ed7-4985-be1b-f5bdcb6ab44d": {"svcId": 1, "displayName": "autotest-1", "instanceUid": "408b7f96-6ed7-4985-be1b-f5bdcb6ab44d"},
|
||||
"884356cf-5212-4395-b56b-27c58a5fc1fa": {"svcId": 1, "displayName": "autotest-1-first", "instanceUid": "884356cf-5212-4395-b56b-27c58a5fc1fa"},
|
||||
"6528854d-a4ea-428c-9fa4-68e85fa9b3ac": {"svcId": 1, "displayName": "curl-test-144834", "instanceUid": "6528854d-a4ea-428c-9fa4-68e85fa9b3ac"},
|
||||
@@ -14,39 +11,20 @@ _INITIAL = {
|
||||
}
|
||||
|
||||
|
||||
def _load():
|
||||
try:
|
||||
with open(_PATH) as f:
|
||||
return json.load(f)
|
||||
except (FileNotFoundError, json.JSONDecodeError):
|
||||
data = dict(_INITIAL)
|
||||
_save(data)
|
||||
return data
|
||||
|
||||
|
||||
def _save(data):
|
||||
with open(_PATH, "w") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
|
||||
def add(instance_uid, svc_id, display_name):
|
||||
with _LOCK:
|
||||
data = _load()
|
||||
data[instance_uid] = {
|
||||
_data[instance_uid] = {
|
||||
"svcId": svc_id,
|
||||
"displayName": display_name,
|
||||
"instanceUid": instance_uid,
|
||||
}
|
||||
_save(data)
|
||||
|
||||
|
||||
def remove(instance_uid):
|
||||
with _LOCK:
|
||||
data = _load()
|
||||
data.pop(instance_uid, None)
|
||||
_save(data)
|
||||
_data.pop(instance_uid, None)
|
||||
|
||||
|
||||
def list_all():
|
||||
with _LOCK:
|
||||
return list(_load().values())
|
||||
return list(_data.values())
|
||||
|
||||
@@ -114,8 +114,10 @@ def api_test():
|
||||
# Записать в трекер СРАЗУ, до фонового потока (поток может умереть под gunicorn)
|
||||
try:
|
||||
tracker_add(instance_uid, svc_id, display_name)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"[TRACKER ERROR] add failed: {e}", flush=True)
|
||||
traceback.print_exc()
|
||||
|
||||
# фоном ждать завершения
|
||||
threading.Thread(target=_finish_op, args=(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, True), daemon=True).start()
|
||||
|
||||
@@ -249,8 +249,7 @@ async function executeOp(params){
|
||||
btn.disabled=false;
|
||||
btn.textContent='Готово';
|
||||
if(sd.status==='OK'){
|
||||
if(selectedOp.opName==='create'){await selectService(SVC_ID);}
|
||||
else{await refreshInstances();}
|
||||
await refreshInstances();
|
||||
}
|
||||
}
|
||||
},2000);
|
||||
@@ -278,8 +277,11 @@ function stopPoll(){
|
||||
async function refreshInstances(){
|
||||
const r=await fetch('/api/operations/'+SVC_ID);
|
||||
const d=await r.json();
|
||||
svcInstances=d.instances||[];
|
||||
// обновить только бейджи статусов
|
||||
const newInsts=d.instances||[];
|
||||
const oldUids=new Set(svcInstances.map(i=>i.instanceUid));
|
||||
const added=newInsts.filter(i=>!oldUids.has(i.instanceUid));
|
||||
svcInstances=newInsts;
|
||||
// обновить бейджи существующих
|
||||
svcInstances.forEach(i=>{
|
||||
const el=document.querySelector(`[data-iuid="${i.instanceUid}"] .badge`);
|
||||
if(el){
|
||||
@@ -287,6 +289,21 @@ async function refreshInstances(){
|
||||
el.className='badge '+(i.explainedStatus==='running'?'badge-success':'');
|
||||
}
|
||||
});
|
||||
// добавить новые инстансы в список (перед кнопкой "+ Создать")
|
||||
if(added.length){
|
||||
const list=document.getElementById('inst-list');
|
||||
const addBtn=list.querySelector('[onclick="startCreate()"]');
|
||||
let html='';
|
||||
added.forEach(i=>{
|
||||
const sc=i.explainedStatus==='running'?'badge-success':'';
|
||||
html+=`<div class="inst-item" onclick="toggleInstance('${i.instanceUid}')" data-iuid="${i.instanceUid}">
|
||||
<span style="flex:1;">${i.displayName}</span>
|
||||
<span class="badge ${sc}" style="font-size:9px;">${i.explainedStatus||'?'}</span>
|
||||
</div>`;
|
||||
html+=`<div class="inst-ops" id="ops-${i.instanceUid}"></div>`;
|
||||
});
|
||||
if(addBtn){addBtn.insertAdjacentHTML('beforebegin',html);}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user