diff --git a/assets/sai.js b/assets/sai.js
index 9b82cb0..2410dd3 100644
--- a/assets/sai.js
+++ b/assets/sai.js
@@ -784,9 +784,14 @@ function createTaskRow(task, now_ut) {
qc++;
}
+ let prefix = "";
+ if (task.git_hash && task.repo_name) {
+ prefix = `<span class="e6">${hsanitize(task.git_hash.substring(0, 4))}</span> ${hsanitize(task.repo_name)} `;
+ }
+
tr.innerHTML = `<td>${s1}</td>` +
`<td>${agify(now_ut, task.started)} ago</td>` +
- `<td><a href="index.html?task=${hsanitize(task.task_uuid)}">${hsanitize(task.task_name)}</a></td>`;
+ `<td>${prefix}<a href="index.html?task=${hsanitize(task.task_uuid)}">${hsanitize(task.task_name)}</a></td>`;
return tr;
}
@@ -799,9 +804,14 @@ function updateTaskRow(tr, task, now_ut) {
s1 += "□";
qc++;
}
+ let prefix = "";
+ if (task.git_hash && task.repo_name) {
+ prefix = `<span class="e6">${hsanitize(task.git_hash.substring(0, 4))}</span> ${hsanitize(task.repo_name)} `;
+ }
+
const newHTML = `<td>${s1}</td>` +
`<td>${agify(now_ut, task.started)} ago</td>` +
- `<td><a href="index.html?task=${hsanitize(task.task_uuid)}">${hsanitize(task.task_name)}</a></td>`;
+ `<td>${prefix}<a href="index.html?task=${hsanitize(task.task_uuid)}">${hsanitize(task.task_name)}</a></td>`;
if (tr.innerHTML !== newHTML) {
tr.innerHTML = newHTML;
@@ -883,6 +893,7 @@ function updateSpreadsheetDOM(container, tasks) {
var pos = 0, lli = 1, lines = "", times = "", locked = 1, tfirst = 0,
cont = [ 0, 0, 0, 0, 0];
+var deleted_events_cache = new Set();
function get_appropriate_ws_url()
{
@@ -1359,9 +1370,7 @@ function refresh_state(task_uuid, task_state)
}
}
-function after_delete() {
- location.reload();
-}
+
function createContextMenu(event, menuItems) {
event.preventDefault();
@@ -1894,6 +1903,12 @@ function ws_open_sai()
}
var s1 = get_appropriate_ws_url() + "/sai/browse" + s;
+ if (typeof gitohashi_integ === 'undefined' || !gitohashi_integ) {
+ if (s1.indexOf('?') !== -1)
+ s1 += "&client=sai";
+ else
+ s1 += "?client=sai";
+ }
// if (s1.split("?"))
// s1 = s1.split("?")[0];
console.log(s1);
@@ -2162,6 +2177,13 @@ function ws_open_sai()
* can send a single e[] if it just changed
* state
*/
+ if (jso.overview) {
+ jso.overview = jso.overview.filter(o => !deleted_events_cache.has(o.e.uuid));
+ if (jso.overview.length === 0 && typeof jso.total_events === 'undefined') {
+ break;
+ }
+ }
+
s = "<table>";
/*
@@ -2193,18 +2215,15 @@ function ws_open_sai()
var pagination_html_top = "";
var pagination_html_bottom = "";
if (!gitohashi_integ && jso.total_events > 6) {
- var info_span = "<span class=\"sai-pagination-info\">Showing " + (jso.offset + 1) + " - " + Math.min(jso.offset + 6, jso.total_events) + " of " + jso.total_events + "</span>";
-
pagination_html_top += "<div class=\"sai-pagination\">";
if (jso.offset > 0) {
- pagination_html_top += "<button class=\"btn sai-pagination-btn\" data-offset=\"" + Math.max(0, jso.offset - 6) + "\">< Newer</button> ";
+ pagination_html_top += "<button class=\"btn sai-pagination-btn\" data-offset=\"" + Math.max(0, jso.offset - 6) + "\">< Newer</button>";
}
- pagination_html_top += info_span + "</div>";
+ pagination_html_top += "</div>";
pagination_html_bottom += "<div class=\"sai-pagination\">";
- pagination_html_bottom += info_span;
if (jso.offset + 6 < jso.total_events) {
- pagination_html_bottom += " <button class=\"btn sai-pagination-btn\" data-offset=\"" + (jso.offset + 6) + "\">Older ></button>";
+ pagination_html_bottom += "<button class=\"btn sai-pagination-btn\" data-offset=\"" + (jso.offset + 6) + "\">Older ></button>";
}
pagination_html_bottom += "</div>";
}
@@ -2276,14 +2295,27 @@ function ws_open_sai()
document.getElementById("delete-ev-" + san(jso.overview[n].e.uuid)).
addEventListener("click", function(e) {
console.log(e);
+ var uuid = san(e.srcElement.id.substring(10));
+ deleted_events_cache.add(uuid);
var rs= "{\"schema\":" +
"\"com.warmcat.sai.eventdelete\"," +
"\"uuid\": " +
- JSON.stringify(san(e.srcElement.id.substring(10))) + "}";
+ JSON.stringify(uuid) + "}";
console.log(rs);
sai.send(rs);
- setTimeout(after_delete, 750);
+ // Remove the event row immediately
+ var td = e.srcElement.closest(".waiting");
+ if (td && td.parentNode) {
+ var tr = td.parentNode;
+ tr.style.transition = 'opacity 0.3s';
+ tr.style.opacity = '0';
+ setTimeout(function() {
+ if (tr && tr.parentNode) {
+ tr.parentNode.removeChild(tr);
+ }
+ }, 300);
+ }
});
}
break;
@@ -2324,10 +2356,12 @@ function ws_open_sai()
if (document.getElementById("taskinfo-" + jso.t.uuid)) {
console.log("FOUND taskinfo-" + jso.t.uuid);
document.getElementById("taskinfo-" + jso.t.uuid).innerHTML = sai_taskinfo_render(jso);
- if (document.getElementById("esr-" + jso.e.uuid))
- document.getElementById("esr-" + jso.e.uuid).innerHTML =
- sai_event_summary_render(jso, now_ut, 1);
- update_summary_and_progress(jso.e.uuid);
+ if (jso.e) {
+ if (document.getElementById("esr-" + jso.e.uuid))
+ document.getElementById("esr-" + jso.e.uuid).innerHTML =
+ sai_event_summary_render(jso, now_ut, 1);
+ update_summary_and_progress(jso.e.uuid);
+ }
} else {
@@ -2367,13 +2401,14 @@ function ws_open_sai()
document.getElementById("sai_overview").innerHTML = s;
logs_pending = times_pending = lines_pending = "";
- if (document.getElementById("esr-" + jso.e.uuid))
+ if (jso.e && document.getElementById("esr-" + jso.e.uuid))
document.getElementById("esr-" + jso.e.uuid).innerHTML =
sai_event_summary_render(jso, now_ut, 1);
}
}
- update_summary_and_progress(jso.e.uuid);
+ if (jso.e)
+ update_summary_and_progress(jso.e.uuid);
if (document.getElementById("rebuild-" + san(jso.t.uuid))) {
document.getElementById("rebuild-" + san(jso.t.uuid)).
diff --git a/src/builder/b-ws-server.c b/src/builder/b-ws-server.c
index 272e84e..31ef5ff 100644
--- a/src/builder/b-ws-server.c
+++ b/src/builder/b-ws-server.c
@@ -519,6 +519,10 @@ saib_sul_load_report_cb(struct lws_sorted_usec_list *sul)
ati->est_peak_mem_kib = ns->task->est_peak_mem_kib;
ati->est_disk_kib = ns->task->est_disk_kib;
ati->started = ns->task->started;
+ if (ns->task->repo_name)
+ lws_strncpy(ati->repo_name, ns->task->repo_name, sizeof(ati->repo_name));
+ if (ns->task->git_hash)
+ lws_strncpy(ati->git_hash, ns->task->git_hash, sizeof(ati->git_hash));
lws_dll2_add_tail(&ati->list, &lr.active_tasks);
lr.active_steps++;
diff --git a/src/common/include/private.h b/src/common/include/private.h
index d316703..eb4f709 100644
--- a/src/common/include/private.h
+++ b/src/common/include/private.h
@@ -83,6 +83,8 @@ typedef struct sai_active_task_info {
unsigned int est_peak_mem_kib;
unsigned int est_disk_kib;
uint64_t started;
+ char repo_name[64];
+ char git_hash[65];
} sai_active_task_info_t;
typedef struct sai_load_report {
diff --git a/src/common/struct-metadata.c b/src/common/struct-metadata.c
index 1c9dd09..a310e10 100644
--- a/src/common/struct-metadata.c
+++ b/src/common/struct-metadata.c
@@ -36,6 +36,8 @@ const lws_struct_map_t lsm_active_task_info[] = {
LSM_UNSIGNED (sai_active_task_info_t, est_peak_mem_kib, "est_peak_mem_kib"),
LSM_UNSIGNED (sai_active_task_info_t, est_disk_kib, "est_disk_kib"),
LSM_UNSIGNED (sai_active_task_info_t, started, "started"),
+ LSM_CARRAY (sai_active_task_info_t, repo_name, "repo_name"),
+ LSM_CARRAY (sai_active_task_info_t, git_hash, "git_hash"),
};
const lws_struct_map_t lsm_load_report_members[] = {
diff --git a/src/web/w-comms.c b/src/web/w-comms.c
index acf5a42..c156d0f 100644
--- a/src/web/w-comms.c
+++ b/src/web/w-comms.c
@@ -448,6 +448,16 @@ http_resp:
pss->wsi = wsi;
pss->vhd = vhd;
+ pss->is_gitohashi = 1;
+ {
+ int r = 0;
+ char tbuf[96];
+ while (lws_hdr_copy_fragment(wsi, tbuf, sizeof(tbuf), WSI_TOKEN_HTTP_URI_ARGS, r++) >= 0) {
+ if (!strncmp(tbuf, "client=sai", 10)) {
+ pss->is_gitohashi = 0;
+ }
+ }
+ }
pss->alang[0] = '\0';
lws_hdr_copy(wsi, pss->alang, sizeof(pss->alang),
WSI_TOKEN_HTTP_ACCEPT_LANGUAGE);
diff --git a/src/web/w-private.h b/src/web/w-private.h
index bdecaab..d4d16a0 100644
--- a/src/web/w-private.h
+++ b/src/web/w-private.h
@@ -62,6 +62,7 @@ enum {
struct pss {
struct vhd *vhd;
struct lws *wsi;
+ uint8_t is_gitohashi:1;
struct lws_spa *spa;
struct lejp_ctx ctx;
@@ -226,6 +227,10 @@ void
saiw_ws_broadcast_browsers_REQUIRES_LWS_PRE(struct vhd *vhd, const void *buf, size_t len,
enum lws_write_protocol flags);
+int
+saiw_ws_browser_queue_REQUIRES_LWS_PRE(struct pss *pss, const void *buf,
+ size_t len, enum lws_write_protocol flags);
+
void
saiw_browser_state_changed(struct pss *pss, int established);
diff --git a/src/web/w-ws-browser.c b/src/web/w-ws-browser.c
index 30c9a36..417a07c 100644
--- a/src/web/w-ws-browser.c
+++ b/src/web/w-ws-browser.c
@@ -520,7 +520,8 @@ saiw_browsers_task_state_change(struct vhd *vhd, const char *task_uuid)
lws_start_foreach_dll(struct lws_dll2 *, p, vhd->browsers.head) {
struct pss *pss = lws_container_of(p, struct pss, same);
- saiw_pss_schedule_taskinfo(pss, task_uuid, 0);
+ if (!pss->is_gitohashi)
+ saiw_pss_schedule_taskinfo(pss, task_uuid, 0);
} lws_end_foreach_dll(p);
return 0;
@@ -533,7 +534,8 @@ saiw_event_state_change(struct vhd *vhd, const char *event_uuid)
lws_start_foreach_dll(struct lws_dll2 *, p, vhd->browsers.head) {
struct pss *pss = lws_container_of(p, struct pss, same);
- saiw_pss_schedule_eventinfo(pss, event_uuid);
+ if (!pss->is_gitohashi)
+ saiw_pss_schedule_eventinfo(pss, event_uuid);
} lws_end_foreach_dll(p);
return 0;
@@ -1026,84 +1028,75 @@ saiw_browser_queue_overview(struct vhd *vhd, struct pss *pss)
e = lws_container_of(walk, sai_event_t, list);
lws_dll2_owner_clear(&task_owner);
- do {
- task_ac = NULL;
-
- if (sai_event_db_ensure_open(vhd->context, &vhd->sqlite3_cache,
- vhd->sqlite3_path_lhs, e->uuid, 0, &pdb)) {
- lwsl_err("%s: unable to open event-specific database\n",
- __func__);
-
- break;
- }
+ task_index = 0;
+ if (sai_event_db_ensure_open(vhd->context, &vhd->sqlite3_cache,
+ vhd->sqlite3_path_lhs, e->uuid, 0, &pdb)) {
+ lwsl_err("%s: unable to open event-specific database\n",
+ __func__);
+ } else {
+ task_ac = NULL;
lws_dll2_owner_clear(&task_owner);
if (lws_struct_sq3_deserialize(pdb, NULL, NULL,
lsm_schema_sq3_map_task, &task_owner,
- &task_ac, (int)task_index, 1)) {
+ &task_ac, 0, 999)) {
lwsl_err("%s: OVERVIEW 1 failed\n", __func__);
- sai_event_db_close(&vhd->sqlite3_cache, &pdb);
-
- break;
+ } else {
+ lws_start_foreach_dll(struct lws_dll2 *, pt, task_owner.head) {
+ t = lws_container_of(pt, sai_task_t, list);
+
+ if (task_index)
+ *p++ = ',';
+
+ /*
+ * We don't want to send everyone the artifact nonces...
+ * the up nonce is a key for uploading artifacts on to
+ * this task, it should only be stored in the server db
+ * and sent to the builder to use.
+ *
+ * The down nonce is used in generated links, but still
+ * you should have to acquire such a link via whatever
+ * auth rather than be able to cook them up yourself
+ * from knowing the task uuid.
+ */
+
+ t->art_up_nonce[0] = '\0';
+ t->art_down_nonce[0] = '\0';
+
+ t->rebuildable = (t->state == SAIES_FAIL || t->state == SAIES_CANCELLED) &&
+ (lws_now_secs() - (t->started + t->duration / 1000000) < 24 * 3600);
+
+ js = lws_struct_json_serialize_create(
+ lsm_schema_json_map_task,
+ LWS_ARRAY_SIZE(lsm_schema_json_map_task), 0, t);
+
+ t->build[0] = '\0';
+
+ do {
+ n = (int)lws_struct_json_serialize(js, (uint8_t *)p, lws_ptr_diff_size_t(end, p), &w);
+ switch (n) {
+ case LSJS_RESULT_FINISH:
+ lws_struct_json_serialize_destroy(&js);
+ p += w;
+ break;
+
+ case LSJS_RESULT_CONTINUE:
+ p += w;
+ saiw_ws_browser_queue_REQUIRES_LWS_PRE(pss, start,
+ lws_ptr_diff_size_t(p, start),
+ lws_write_ws_flags(LWS_WRITE_TEXT, 0, 0));
+ p = start;
+ break;
+ }
+ } while (n == LSJS_RESULT_CONTINUE);
+
+ task_index++;
+ } lws_end_foreach_dll(pt);
}
- sai_event_db_close(&vhd->sqlite3_cache, &pdb);
-
- if (!task_owner.count)
- break;
-
- if (task_index)
- *p++ = ',';
-
- /*
- * We don't want to send everyone the artifact nonces...
- * the up nonce is a key for uploading artifacts on to
- * this task, it should only be stored in the server db
- * and sent to the builder to use.
- *
- * The down nonce is used in generated links, but still
- * you should have to acquire such a link via whatever
- * auth rather than be able to cook them up yourself
- * from knowing the task uuid.
- */
-
- t = (sai_task_t *)task_owner.head;
- t->art_up_nonce[0] = '\0';
- t->art_down_nonce[0] = '\0';
-
- t->rebuildable = (t->state == SAIES_FAIL || t->state == SAIES_CANCELLED) &&
- (lws_now_secs() - (t->started + t->duration / 1000000) < 24 * 3600);
-
- /* only one in it at a time */
- t = lws_container_of(task_owner.head, sai_task_t, list);
-
- js = lws_struct_json_serialize_create(
- lsm_schema_json_map_task,
- LWS_ARRAY_SIZE(lsm_schema_json_map_task), 0, t);
-
- t->build[0] = '\0';
-
- do {
- n = (int)lws_struct_json_serialize(js, (uint8_t *)p, lws_ptr_diff_size_t(end, p), &w);
- switch (n) {
- case LSJS_RESULT_FINISH:
- lws_struct_json_serialize_destroy(&js);
- p += w;
- break;
-
- case LSJS_RESULT_CONTINUE:
- p += w;
- saiw_ws_browser_queue_REQUIRES_LWS_PRE(pss, start,
- lws_ptr_diff_size_t(p, start),
- lws_write_ws_flags(LWS_WRITE_TEXT, 0, 0));
- p = start;
- break;
- }
- } while (n == LSJS_RESULT_CONTINUE);
lwsac_free(&task_ac);
-
- task_index++;
- } while (1);
+ sai_event_db_close(&vhd->sqlite3_cache, &pdb);
+ }
/* none left to do, go back up a level */
diff --git a/src/web/w-ws-server.c b/src/web/w-ws-server.c
index e31a7e4..a994150 100644
--- a/src/web/w-ws-server.c
+++ b/src/web/w-ws-server.c
@@ -125,13 +125,20 @@ saiw_lp_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
* "schema" member is parsed, even on the first fragment.
*/
switch (m->a.top_schema_index) {
- case SAIS_WS_WEBSRV_RX_LOADREPORT:
case SAIS_WS_WEBSRV_RX_TASKACTIVITY:
saiw_ws_broadcast_browsers_REQUIRES_LWS_PRE(vhd, p, rem,
lws_write_ws_flags(LWS_WRITE_TEXT,
is_start,
0)); /* Not EOM */
break;
+ case SAIS_WS_WEBSRV_RX_LOADREPORT:
+ lws_start_foreach_dll(struct lws_dll2 *, pt, vhd->browsers.head) {
+ struct pss *pss = lws_container_of(pt, struct pss, same);
+ if (!pss->is_gitohashi)
+ saiw_ws_browser_queue_REQUIRES_LWS_PRE(pss, p, rem,
+ lws_write_ws_flags(LWS_WRITE_TEXT, is_start, 0));
+ } lws_end_foreach_dll(pt);
+ break;
default:
// lwsl_err("%s: SWALLOWING %.*s\n", __func__, (int)len, buf);
break;
@@ -148,13 +155,20 @@ saiw_lp_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
switch (m->a.top_schema_index) {
case SAIS_WS_WEBSRV_RX_TASKCHANGE:
case SAIS_WS_WEBSRV_RX_EVENTCHANGE:
- case SAIS_WS_WEBSRV_RX_LOADREPORT:
case SAIS_WS_WEBSRV_RX_TASKACTIVITY:
saiw_ws_broadcast_browsers_REQUIRES_LWS_PRE(vhd, p, consumed,
lws_write_ws_flags(LWS_WRITE_TEXT,
is_start,
1)); /* Force EOM */
break;
+ case SAIS_WS_WEBSRV_RX_LOADREPORT:
+ lws_start_foreach_dll(struct lws_dll2 *, pt, vhd->browsers.head) {
+ struct pss *pss = lws_container_of(pt, struct pss, same);
+ if (!pss->is_gitohashi)
+ saiw_ws_browser_queue_REQUIRES_LWS_PRE(pss, p, consumed,
+ lws_write_ws_flags(LWS_WRITE_TEXT, is_start, 1));
+ } lws_end_foreach_dll(pt);
+ break;
}
/*
@@ -199,7 +213,8 @@ saiw_lp_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
lws_start_foreach_dll(struct lws_dll2 *, p, vhd->browsers.head) {
struct pss *pss = lws_container_of(p, struct pss, same);
- saiw_browser_broadcast_queue_builders(pss->vhd, pss);
+ if (!pss->is_gitohashi)
+ saiw_browser_broadcast_queue_builders(pss->vhd, pss);
} lws_end_foreach_dll(p);
break;
@@ -222,7 +237,8 @@ saiw_lp_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
lws_start_foreach_dll(struct lws_dll2 *, p, vhd->browsers.head) {
struct pss *pss = lws_container_of(p, struct pss, same);
- saiw_browser_broadcast_queue_builders(pss->vhd, pss);
+ if (!pss->is_gitohashi)
+ saiw_browser_broadcast_queue_pcons(pss->vhd, pss);
} lws_end_foreach_dll(p);
break;
@@ -231,8 +247,10 @@ saiw_lp_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
lws_start_foreach_dll(struct lws_dll2 *, p, vhd->browsers.head) {
struct pss *pss = lws_container_of(p, struct pss, same);
- saiw_browser_broadcast_queue_power_history(pss->vhd, pss);
- saiw_browser_broadcast_queue_pcon_energy(pss->vhd, pss, (sai_pcon_energy_report_t *)m->a.dest);
+ if (!pss->is_gitohashi) {
+ saiw_browser_broadcast_queue_power_history(pss->vhd, pss);
+ saiw_browser_broadcast_queue_pcon_energy(pss->vhd, pss, (sai_pcon_energy_report_t *)m->a.dest);
+ }
} lws_end_foreach_dll(p);
break;