Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
Author[]google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.c...> 2025-08-23 06:29 UTC
Committer[]Andy Green <andy@warmcat.com> 2025-08-23 08:34 UTC
Tree06a717c198468f0c6f8f838a3826699c32121dc8   Raw Patch
 
sai-server: async database reties against BUSY
sai-server: async database reties against BUSY
diff --git a/assets/sai.js b/assets/sai.js index 325f3f1..707caef 100644 --- a/assets/sai.js +++ b/assets/sai.js @@ -974,6 +974,8 @@ function createBuilderDiv(plat) { ]; platDiv.addEventListener("contextmenu", function(event) { + if (!authd) + return; createContextMenu(event, menuItems); }); @@ -1007,7 +1009,8 @@ function createBuilderDiv(plat) { pageX: touchStartPos.x, pageY: touchStartPos.y }; - createContextMenu(mockEvent, menuItems); + if (authd) + createContextMenu(mockEvent, menuItems); } touchStartTime = 0; }); @@ -1462,7 +1465,7 @@ function ws_open_sai() 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.e, now_ut, 1); + sai_event_summary_render(jso, now_ut, 1); } else { console.log("NO taskinfo- or taskstate_" + jso.t.uuid); diff --git a/src/builder/b-mirror.c b/src/builder/b-mirror.c index 9c63b3a..2be2e16 100644 --- a/src/builder/b-mirror.c +++ b/src/builder/b-mirror.c @@ -43,22 +43,31 @@ static const char * const git_helper_sh = " REF=$2\n" " HASH=$3\n" " MIRROR_PATH=$4\n" - " while ! mkdir \"$MIRROR_PATH.lock\" 2>/dev/null; do\n" - " echo \"git mirror locked, waiting...\"\n" - " sleep 1\n" - " done\n" - " trap 'rm -rf \"$MIRROR_PATH.lock\"' EXIT\n" - " if [ -d \"$MIRROR_PATH/.git\" ]; then\n" - " if git -C \"$MIRROR_PATH\" rev-parse -q --verify \"ref-$HASH\" > /dev/null; then\n" + " for i in $(seq 1 60); do\n" + " if [ -d \"$MIRROR_PATH/.git\" ]; then\n" + " if git -C \"$MIRROR_PATH\" rev-parse -q --verify \"ref-$HASH\" > /dev/null; then\n" + " exit 0\n" + " fi\n" + " fi\n" + " if mkdir \"$MIRROR_PATH.lock\" 2>/dev/null; then\n" + " trap 'rm -rf \"$MIRROR_PATH.lock\"' EXIT\n" + " if [ -d \"$MIRROR_PATH/.git\" ]; then\n" + " if git -C \"$MIRROR_PATH\" rev-parse -q --verify \"ref-$HASH\" > /dev/null; then\n" + " exit 0\n" + " fi\n" + " fi\n" + " mkdir -p \"$MIRROR_PATH\"\n" + " if [ ! -d \"$MIRROR_PATH/.git\" ]; then\n" + " git init --bare \"$MIRROR_PATH\"\n" + " fi\n" + " REFSPEC=\"$REF:ref-$HASH\"\n" + " git -C \"$MIRROR_PATH\" fetch \"$REMOTE_URL\" \"+$REFSPEC\"\n" " exit 0\n" " fi\n" - " fi\n" - " mkdir -p \"$MIRROR_PATH\"\n" - " if [ ! -d \"$MIRROR_PATH/.git\" ]; then\n" - " git init --bare \"$MIRROR_PATH\"\n" - " fi\n" - " REFSPEC=\"$REF:ref-$HASH\"\n" - " git -C \"$MIRROR_PATH\" fetch \"$REMOTE_URL\" \"+$REFSPEC\"\n" + " echo \"git mirror locked, waiting...\"\n" + " sleep 1\n" + " done\n" + " exit 1\n" "elif [ \"$OPERATION\" == \"checkout\" ]; then\n" " MIRROR_PATH=$1\n" " BUILD_DIR=$2\n" diff --git a/src/server/s-private.h b/src/server/s-private.h index 4b3366b..d73368e 100644 --- a/src/server/s-private.h +++ b/src/server/s-private.h @@ -28,6 +28,12 @@ struct sai_plat; +typedef enum { + SAI_DB_RESULT_OK, + SAI_DB_RESULT_BUSY, + SAI_DB_RESULT_ERROR, +} sai_db_result_t; + typedef struct sai_platm { lws_dll2_owner_t builder_owner; lws_dll2_owner_t subs_owner; @@ -291,7 +297,7 @@ sais_central_cb(lws_sorted_usec_list_t *sul); void sais_activity_cb(lws_sorted_usec_list_t *sul); -int +sai_db_result_t sais_task_reset(struct vhd *vhd, const char *task_uuid); int diff --git a/src/server/s-task.c b/src/server/s-task.c index 72b6575..46f19b8 100644 --- a/src/server/s-task.c +++ b/src/server/s-task.c @@ -724,14 +724,15 @@ sais_task_cancel(struct vhd *vhd, const char *task_uuid) * it and reset the task state back to WAITING. */ -int +sai_db_result_t sais_task_reset(struct vhd *vhd, const char *task_uuid) { char esc[96], cmd[256], event_uuid[33]; sqlite3 *pdb = NULL; + int ret; if (!task_uuid[0]) - return 0; + return SAI_DB_RESULT_OK; lwsl_notice("%s: received request to reset task %s\n", __func__, task_uuid); @@ -741,23 +742,35 @@ sais_task_reset(struct vhd *vhd, const char *task_uuid) lwsl_err("%s: unable to open event-specific database\n", __func__); - return -1; + return SAI_DB_RESULT_ERROR; } lws_sql_purify(esc, task_uuid, sizeof(esc)); lws_snprintf(cmd, sizeof(cmd), "delete from logs where task_uuid='%s'", esc); - if (sqlite3_exec(pdb, cmd, NULL, NULL, NULL) != SQLITE_OK) { + ret = sqlite3_exec(pdb, cmd, NULL, NULL, NULL); + if (ret != SQLITE_OK) { sais_event_db_close(vhd, &pdb); + if (ret == SQLITE_BUSY) + return SAI_DB_RESULT_BUSY; lwsl_err("%s: %s: %s: fail\n", __func__, cmd, - sqlite3_errmsg(vhd->server.pdb)); - return 1; + sqlite3_errmsg(pdb)); + return SAI_DB_RESULT_ERROR; } lws_snprintf(cmd, sizeof(cmd), "delete from artifacts where task_uuid='%s'", esc); - sqlite3_exec(pdb, cmd, NULL, NULL, NULL); + ret = sqlite3_exec(pdb, cmd, NULL, NULL, NULL); + if (ret != SQLITE_OK) { + sais_event_db_close(vhd, &pdb); + if (ret == SQLITE_BUSY) + return SAI_DB_RESULT_BUSY; + lwsl_err("%s: %s: %s: fail\n", __func__, cmd, + sqlite3_errmsg(pdb)); + return SAI_DB_RESULT_ERROR; + } + sais_event_db_close(vhd, &pdb); sais_set_task_state(vhd, NULL, NULL, task_uuid, SAIES_WAITING, 1, 1); @@ -776,7 +789,7 @@ sais_task_reset(struct vhd *vhd, const char *task_uuid) */ sais_platforms_with_tasks_pending(vhd); - return 0; + return SAI_DB_RESULT_OK; } /* diff --git a/src/server/s-websrv.c b/src/server/s-websrv.c index 419c917..ded8f52 100644 --- a/src/server/s-websrv.c +++ b/src/server/s-websrv.c @@ -40,6 +40,18 @@ #include "s-private.h" +typedef struct sai_sul_retry_ctx { + lws_sorted_usec_list_t sul; + struct vhd *vhd; + char uuid[SAI_TASKID_LEN + 1]; + char platform[96]; + int retries; + uint8_t op; /* SAIS_WS_WEBSRV_RX_... */ +} sai_sul_retry_ctx_t; + +static void +sais_websrv_retry_cb(lws_sorted_usec_list_t *sul); + typedef struct websrvss_srv { struct lws_ss_handle *ss; struct vhd *vhd; @@ -371,15 +383,222 @@ sum_viewers_cb(struct lws_ss_handle *h, void *arg) *(unsigned int *)arg += m_client->viewers; } +static sai_db_result_t +sais_event_reset(struct vhd *vhd, const char *event_uuid) +{ + sqlite3 *pdb = NULL; + lws_dll2_owner_t o; + struct lwsac *ac = NULL; + char *err = NULL; + int ret; + + if (sais_event_db_ensure_open(vhd, event_uuid, 0, &pdb)) + return SAI_DB_RESULT_ERROR; + + if (lws_struct_sq3_deserialize(pdb, NULL, NULL, + lsm_schema_sq3_map_task, + &o, &ac, 0, 999) >= 0) { + + ret = sqlite3_exec(pdb, "BEGIN TRANSACTION", NULL, NULL, &err); + if (ret != SQLITE_OK) { + sais_event_db_close(vhd, &pdb); + lwsac_free(&ac); + if (ret == SQLITE_BUSY) + return SAI_DB_RESULT_BUSY; + return SAI_DB_RESULT_ERROR; + } + sqlite3_free(err); + + lws_start_foreach_dll(struct lws_dll2 *, p, o.head) { + sai_task_t *t = lws_container_of(p, sai_task_t, list); + if (sais_task_reset(vhd, t->uuid) == SAI_DB_RESULT_BUSY) { + sqlite3_exec(pdb, "END TRANSACTION", NULL, NULL, &err); + sais_event_db_close(vhd, &pdb); + lwsac_free(&ac); + return SAI_DB_RESULT_BUSY; + } + } lws_end_foreach_dll(p); + + ret = sqlite3_exec(pdb, "END TRANSACTION", NULL, NULL, &err); + if (ret != SQLITE_OK) { + sais_event_db_close(vhd, &pdb); + lwsac_free(&ac); + if (ret == SQLITE_BUSY) + return SAI_DB_RESULT_BUSY; + return SAI_DB_RESULT_ERROR; + } + sqlite3_free(err); + } + + sais_event_db_close(vhd, &pdb); + lwsac_free(&ac); + + return SAI_DB_RESULT_OK; +} + +sai_db_result_t +sais_event_delete(struct vhd *vhd, const char *event_uuid) +{ + sqlite3 *pdb = NULL; + lws_dll2_owner_t o; + struct lwsac *ac = NULL; + char *err = NULL; + int ret; + char qu[128], esc[96]; + + if (sais_event_db_ensure_open(vhd, event_uuid, 0, &pdb) == 0) { + if (lws_struct_sq3_deserialize(pdb, NULL, NULL, + lsm_schema_sq3_map_task, + &o, &ac, 0, 999) >= 0) { + + ret = sqlite3_exec(pdb, "BEGIN TRANSACTION", NULL, NULL, &err); + if (ret != SQLITE_OK) { + sais_event_db_close(vhd, &pdb); + lwsac_free(&ac); + if (ret == SQLITE_BUSY) + return SAI_DB_RESULT_BUSY; + return SAI_DB_RESULT_ERROR; + } + + lws_start_foreach_dll(struct lws_dll2 *, p, o.head) { + sai_task_t *t = lws_container_of(p, sai_task_t, list); + + if (t->state != SAIES_WAITING && + t->state != SAIES_SUCCESS && + t->state != SAIES_FAIL && + t->state != SAIES_CANCELLED) + sais_task_cancel(vhd, t->uuid); + + } lws_end_foreach_dll(p); + + ret = sqlite3_exec(pdb, "END TRANSACTION", NULL, NULL, &err); + if (ret != SQLITE_OK) { + sais_event_db_close(vhd, &pdb); + lwsac_free(&ac); + if (ret == SQLITE_BUSY) + return SAI_DB_RESULT_BUSY; + return SAI_DB_RESULT_ERROR; + } + } + sais_event_db_close(vhd, &pdb); + lwsac_free(&ac); + } + + lws_sql_purify(esc, event_uuid, sizeof(esc)); + lws_snprintf(qu, sizeof(qu), "delete from events where uuid='%s'", esc); + ret = sqlite3_exec(vhd->server.pdb, qu, NULL, NULL, &err); + if (ret != SQLITE_OK) { + if (ret == SQLITE_BUSY) + return SAI_DB_RESULT_BUSY; + lwsl_err("%s: evdel uuid %s, sq3 err %s\n", __func__, esc, err); + sqlite3_free(err); + return SAI_DB_RESULT_ERROR; + } + + sais_event_db_delete_database(vhd, event_uuid); + sais_eventchange(vhd->h_ss_websrv, event_uuid, SAIES_DELETED); + sais_websrv_broadcast(vhd->h_ss_websrv, + "{\"schema\":\"sai-overview\"}", 25); + + return SAI_DB_RESULT_OK; +} + +static sai_db_result_t +sais_plat_reset(struct vhd *vhd, const char *event_uuid, const char *platform) +{ + sqlite3 *pdb = NULL; + lws_dll2_owner_t o; + struct lwsac *ac = NULL; + char *err = NULL; + int ret; + char filt[256], esc[96]; + + if (sais_event_db_ensure_open(vhd, event_uuid, 0, &pdb)) + return SAI_DB_RESULT_ERROR; + + lws_sql_purify(esc, platform, sizeof(esc)); + lws_snprintf(filt, sizeof(filt), " and platform='%s' and state=4", esc); + + if (lws_struct_sq3_deserialize(pdb, filt, NULL, + lsm_schema_sq3_map_task, + &o, &ac, 0, 999) >= 0) { + ret = sqlite3_exec(pdb, "BEGIN TRANSACTION", NULL, NULL, &err); + if (ret != SQLITE_OK) { + sais_event_db_close(vhd, &pdb); + lwsac_free(&ac); + if (ret == SQLITE_BUSY) + return SAI_DB_RESULT_BUSY; + return SAI_DB_RESULT_ERROR; + } + sqlite3_free(err); + + lws_start_foreach_dll(struct lws_dll2 *, p, o.head) { + sai_task_t *t = lws_container_of(p, sai_task_t, list); + if (sais_task_reset(vhd, t->uuid) == SAI_DB_RESULT_BUSY) { + sqlite3_exec(pdb, "END TRANSACTION", NULL, NULL, &err); + sais_event_db_close(vhd, &pdb); + lwsac_free(&ac); + return SAI_DB_RESULT_BUSY; + } + } lws_end_foreach_dll(p); + + ret = sqlite3_exec(pdb, "END TRANSACTION", NULL, NULL, &err); + if (ret != SQLITE_OK) { + sais_event_db_close(vhd, &pdb); + lwsac_free(&ac); + if (ret == SQLITE_BUSY) + return SAI_DB_RESULT_BUSY; + return SAI_DB_RESULT_ERROR; + } + sqlite3_free(err); + } + + sais_event_db_close(vhd, &pdb); + lwsac_free(&ac); + + return SAI_DB_RESULT_OK; +} + +static void +sais_websrv_retry_cb(lws_sorted_usec_list_t *sul) +{ + sai_sul_retry_ctx_t *ctx = lws_container_of(sul, sai_sul_retry_ctx_t, sul); + sai_db_result_t r = SAI_DB_RESULT_ERROR; + + switch(ctx->op) { + case SAIS_WS_WEBSRV_RX_TASKRESET: + r = sais_task_reset(ctx->vhd, ctx->uuid); + break; + case SAIS_WS_WEBSRV_RX_EVENTRESET: + r = sais_event_reset(ctx->vhd, ctx->uuid); + break; + case SAIS_WS_WEBSRV_RX_EVENTDELETE: + r = sais_event_delete(ctx->vhd, ctx->uuid); + break; + case SAIS_WS_WEBSRV_RX_PLATRESET: + r = sais_plat_reset(ctx->vhd, ctx->uuid, ctx->platform); + break; + } + + if (r == SAI_DB_RESULT_BUSY && ctx->retries-- > 0) { + lwsl_notice("Retrying op %d for %s\n", ctx->op, ctx->uuid); + lws_sul_schedule(ctx->vhd->context, 0, &ctx->sul, + sais_websrv_retry_cb, 250 * LWS_US_PER_MS); + return; + } + + if (r != SAI_DB_RESULT_OK) + lwsl_err("Failed op %d for %s after retries\n", ctx->op, ctx->uuid); + + free(ctx); +} + static lws_ss_state_return_t websrvss_ws_rx(void *userobj, const uint8_t *buf, size_t len, int flags) { websrvss_srv_t *m = (websrvss_srv_t *)userobj; - char qu[128], esc[96], *err = NULL; sai_browse_rx_evinfo_t *ei; - sqlite3 *pdb = NULL; lws_struct_args_t a; - lws_dll2_owner_t o; int n; // lwsl_user("%s: len %d, flags: %d\n", __func__, (int)len, flags); @@ -404,120 +623,84 @@ websrvss_ws_rx(void *userobj, const uint8_t *buf, size_t len, int flags) switch (a.top_schema_index) { case SAIS_WS_WEBSRV_RX_TASKRESET: + { + sai_db_result_t r; ei = (sai_browse_rx_evinfo_t *)a.dest; if (sais_validate_id(ei->event_hash, SAI_TASKID_LEN)) goto soft_error; - sais_task_reset(m->vhd, ei->event_hash); + r = sais_task_reset(m->vhd, ei->event_hash); + if (r == SAI_DB_RESULT_BUSY) { + sai_sul_retry_ctx_t *ctx = malloc(sizeof(*ctx)); + + if (!ctx) + break; + + ctx->vhd = m->vhd; + lws_strncpy(ctx->uuid, ei->event_hash, sizeof(ctx->uuid)); + ctx->retries = 10; + ctx->op = SAIS_WS_WEBSRV_RX_TASKRESET; + lws_sul_schedule(m->vhd->context, 0, &ctx->sul, + sais_websrv_retry_cb, 250 * LWS_US_PER_MS); + } break; + } case SAIS_WS_WEBSRV_RX_EVENTRESET: + { + sai_db_result_t r; ei = (sai_browse_rx_evinfo_t *)a.dest; if (sais_validate_id(ei->event_hash, SAI_EVENTID_LEN)) goto soft_error; - /* open the event-specific database object */ - - if (sais_event_db_ensure_open(m->vhd, ei->event_hash, 0, &pdb)) { - lwsl_err("%s: unable to open event-specific database\n", - __func__); - /* - * hanging up isn't a good way to deal with browser - * tabs left open with a live connection to a - * now-deleted task... the page will reconnect endlessly - */ - goto soft_error; - } - - /* - * Retreive all the related structs into a dll2 list - */ - - lws_sql_purify(esc, ei->event_hash, sizeof(esc)); - - if (lws_struct_sq3_deserialize(pdb, NULL, NULL, - lsm_schema_sq3_map_task, - &o, &a.ac, 0, 999) >= 0) { - - sqlite3_exec(pdb, "BEGIN TRANSACTION", - NULL, NULL, &err); - sqlite3_free(err); + r = sais_event_reset(m->vhd, ei->event_hash); + if (r == SAI_DB_RESULT_BUSY) { + sai_sul_retry_ctx_t *ctx = malloc(sizeof(*ctx)); - /* - * Walk the results list resetting all the tasks - */ - - lws_start_foreach_dll(struct lws_dll2 *, p, o.head) { - sai_task_t *t = lws_container_of(p, sai_task_t, - list); - - sais_task_reset(m->vhd, t->uuid); - - } lws_end_foreach_dll(p); + if (!ctx) + break; - sqlite3_exec(pdb, "END TRANSACTION", - NULL, NULL, &err); - sqlite3_free(err); + ctx->vhd = m->vhd; + lws_strncpy(ctx->uuid, ei->event_hash, sizeof(ctx->uuid)); + ctx->retries = 10; + ctx->op = SAIS_WS_WEBSRV_RX_EVENTRESET; + lws_sul_schedule(m->vhd->context, 0, &ctx->sul, + sais_websrv_retry_cb, 250 * LWS_US_PER_MS); } - - sais_event_db_close(m->vhd, &pdb); lwsac_free(&a.ac); - - return 0; + break; + } case SAIS_WS_WEBSRV_RX_PLATRESET: { sai_browse_rx_platreset_t *pr = (sai_browse_rx_platreset_t *)a.dest; - char filt[256]; + sai_db_result_t r; if (sais_validate_id(pr->event_uuid, SAI_EVENTID_LEN)) goto soft_error; - /* open the event-specific database object */ - - if (sais_event_db_ensure_open(m->vhd, pr->event_uuid, 0, &pdb)) { - lwsl_err("%s: unable to open event-specific database\n", - __func__); - goto soft_error; - } - - /* - * Retreive all the related structs into a dll2 list - */ - lws_sql_purify(esc, pr->platform, sizeof(esc)); - lws_snprintf(filt, sizeof(filt), " and platform='%s'", esc); - - if (lws_struct_sq3_deserialize(pdb, filt, NULL, - lsm_schema_sq3_map_task, - &o, &a.ac, 0, 999) >= 0) { - - sqlite3_exec(pdb, "BEGIN TRANSACTION", - NULL, NULL, &err); - sqlite3_free(err); - - /* - * Walk the results list resetting all the tasks - */ - - lws_start_foreach_dll(struct lws_dll2 *, p, o.head) { - sai_task_t *t = lws_container_of(p, sai_task_t, - list); - sais_task_reset(m->vhd, t->uuid); - } lws_end_foreach_dll(p); + r = sais_plat_reset(m->vhd, pr->event_uuid, pr->platform); + if (r == SAI_DB_RESULT_BUSY) { + sai_sul_retry_ctx_t *ctx = malloc(sizeof(*ctx)); + if (!ctx) + break; - sqlite3_exec(pdb, "END TRANSACTION", - NULL, NULL, &err); - sqlite3_free(err); + ctx->vhd = m->vhd; + lws_strncpy(ctx->uuid, pr->event_uuid, sizeof(ctx->uuid)); + lws_strncpy(ctx->platform, pr->platform, sizeof(ctx->platform)); + ctx->retries = 10; + ctx->op = SAIS_WS_WEBSRV_RX_PLATRESET; + lws_sul_schedule(m->vhd->context, 0, &ctx->sul, + sais_websrv_retry_cb, 250 * LWS_US_PER_MS); } - - sais_event_db_close(m->vhd, &pdb); lwsac_free(&a.ac); - - return 0; + break; } case SAIS_WS_WEBSRV_RX_EVENTDELETE: + { + sai_db_result_t r; ei = (sai_browse_rx_evinfo_t *)a.dest; if (sais_validate_id(ei->event_hash, SAI_EVENTID_LEN)) { @@ -527,80 +710,22 @@ websrvss_ws_rx(void *userobj, const uint8_t *buf, size_t len, int flags) lwsl_notice("%s: eventdelete %s\n", __func__, ei->event_hash); - /* open the event-specific database object */ - - if (sais_event_db_ensure_open(m->vhd, ei->event_hash, 0, &pdb)) { - lwsl_notice("%s: unable to open event-specific database\n", - __func__); - /* - * hanging up isn't a good way to deal with browser - * tabs left open with a live connection to a - * now-deleted task... the page will reconnect endlessly - */ - - // goto soft_error; - } else { - - /* - * Retreive all the related structs into a dll2 list - */ - - lws_sql_purify(esc, ei->event_hash, sizeof(esc)); - - if (lws_struct_sq3_deserialize(pdb, NULL, NULL, - lsm_schema_sq3_map_task, - &o, &a.ac, 0, 999) >= 0) { - - sqlite3_exec(pdb, "BEGIN TRANSACTION", - NULL, NULL, &err); - - /* - * Walk the results list cancelling all the tasks - * that look like they might be ongoing - */ - - lws_start_foreach_dll(struct lws_dll2 *, p, o.head) { - sai_task_t *t = lws_container_of(p, sai_task_t, - list); - - if (t->state != SAIES_WAITING && - t->state != SAIES_SUCCESS && - t->state != SAIES_FAIL && - t->state != SAIES_CANCELLED) - sais_task_cancel(m->vhd, t->uuid); - - } lws_end_foreach_dll(p); - - sqlite3_exec(pdb, "END TRANSACTION", - NULL, NULL, &err); - } - - sais_event_db_close(m->vhd, &pdb); - } - - /* delete the event iself */ + r = sais_event_delete(m->vhd, ei->event_hash); + if (r == SAI_DB_RESULT_BUSY) { + sai_sul_retry_ctx_t *ctx = malloc(sizeof(*ctx)); + if (!ctx) + break; - lws_sql_purify(esc, ei->event_hash, sizeof(esc)); - lws_snprintf(qu, sizeof(qu), "delete from events where uuid='%s'", - esc); - sqlite3_exec(m->vhd->server.pdb, qu, NULL, NULL, &err); - if (err) { - lwsl_err("%s: evdel uuid %s, sq3 err %s\n", __func__, - esc, err); - sqlite3_free(err); + ctx->vhd = m->vhd; + lws_strncpy(ctx->uuid, ei->event_hash, sizeof(ctx->uuid)); + ctx->retries = 10; + ctx->op = SAIS_WS_WEBSRV_RX_EVENTDELETE; + lws_sul_schedule(m->vhd->context, 0, &ctx->sul, + sais_websrv_retry_cb, 250 * LWS_US_PER_MS); } - - /* remove the event-specific database */ - - sais_event_db_delete_database(m->vhd, ei->event_hash); - lwsac_free(&a.ac); - sais_eventchange(m->vhd->h_ss_websrv, ei->event_hash, - SAIES_DELETED); - sais_websrv_broadcast(m->vhd->h_ss_websrv, - "{\"schema\":\"sai-overview\"}", 25); - - return 0; + break; + } case SAIS_WS_WEBSRV_RX_TASKCANCEL:
Page fetched 0s ago, creation time: 36ms (vhost etag hits: 0%, cache hits: 0%)