Log delayed answer validation and keep JSON percentages locale independent
This commit is contained in:
1 parent
e6db9fef60
commit
865e4cda59
1 file changed
+24
-4
+24
-4
@@ -159,9 +159,10 @@ int chat_feedback_snapshot(struct UTUN_INSTANCE* inst, const char* channel, cons
|
||||
poll.mode == CHAT_POLL_SINGLE ? "single" : "multiple", poll.allow_custom_answer ? "true" : "false") < 0
|
||||
|| strbuf_add_json_string(&out, poll.question) < 0 || strbuf_addf(&out, ",\"options\":[") < 0) goto done;
|
||||
for (unsigned i = 0; i < poll.option_count; i++) {
|
||||
unsigned percent = voters ? (unsigned)((10000ULL * votes[i] + voters / 2) / voters) : 0;
|
||||
if (strbuf_addf(&out, "%s{\"id\":%u,\"text\":", i ? "," : "", i) < 0
|
||||
|| strbuf_add_json_string(&out, poll.options[i]) < 0
|
||||
|| strbuf_addf(&out, ",\"count\":%u,\"percent\":%.2f}", votes[i], voters ? 100.0 * votes[i] / voters : 0.0) < 0) goto done;
|
||||
|| strbuf_addf(&out, ",\"count\":%u,\"percent\":%u.%02u}", votes[i], percent / 100, percent % 100) < 0) goto done;
|
||||
}
|
||||
if (strbuf_addf(&out, "],\"voters\":%u,\"custom_count\":%u,\"ver\":%llu,\"mine\":",
|
||||
voters, custom_count, (unsigned long long)answer_ver) < 0
|
||||
@@ -179,10 +180,29 @@ done:
|
||||
|
||||
/* Сохраняем диагностику семантики при новом состоянии/получении исходного сообщения. */
|
||||
void chat_feedback_check_message(struct UTUN_INSTANCE* inst, const char* channel, const uint8_t message_id[32]) {
|
||||
char* snapshot = NULL;
|
||||
if (chat_feedback_snapshot(inst, channel, message_id, &snapshot) == 0) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CHAT_SYNC, "poll: evaluated ch=%s state=%s", channel, snapshot); u_free(snapshot);
|
||||
struct chat_poll poll; int is_poll, target = poll_target(inst, channel, message_id, &poll, &is_poll);
|
||||
if (target < 0) return;
|
||||
if (target) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CHAT_SYNC, "poll: evaluation deferred ch=%s; source message missing", channel); return;
|
||||
}
|
||||
char sql[256]; snprintf(sql, sizeof(sql),
|
||||
"SELECT node_id,ver,data FROM feedback_%s WHERE message_id=? AND kind=2 AND length(data)>0", channel);
|
||||
sqlite3_stmt* st = NULL;
|
||||
if (sqlite3_prepare_v2(inst->topo_sqlite_db, sql, -1, &st, NULL) != SQLITE_OK) { poll_db_error(inst, "evaluate query"); return; }
|
||||
sqlite3_bind_blob(st, 1, message_id, 32, SQLITE_STATIC); int step; unsigned accepted = 0, rejected = 0;
|
||||
while ((step = sqlite3_step(st)) == SQLITE_ROW) {
|
||||
struct chat_poll_answer answer;
|
||||
if (chat_answer_decode(sqlite3_column_blob(st, 2), sqlite3_column_bytes(st, 2), &answer) < 0
|
||||
|| !is_poll || !poll_answer_allowed(&poll, &answer)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "poll: answer excluded ch=%s node=%016llx ver=%llu poll=%d mode=%u options=%u custom=%u",
|
||||
channel, (unsigned long long)sqlite3_column_int64(st, 0), (unsigned long long)sqlite3_column_int64(st, 1),
|
||||
is_poll, is_poll ? poll.mode : 0, is_poll ? poll.option_count : 0, is_poll ? poll.allow_custom_answer : 0);
|
||||
rejected++;
|
||||
} else accepted++;
|
||||
}
|
||||
sqlite3_finalize(st);
|
||||
if (step != SQLITE_DONE) { poll_db_error(inst, "evaluate read"); return; }
|
||||
if (accepted || rejected) DEBUG_DEBUG(DEBUG_CATEGORY_CHAT_SYNC, "poll: evaluated ch=%s valid=%u invalid=%u", channel, accepted, rejected);
|
||||
}
|
||||
|
||||
/* Читает поле JSON с его типом. Отсутствующее поле имеет type=NULL. */
|
||||
|
||||
Reference in new issue
Block a user