zulip/static/js/sent_messages.js

173 lines
3.8 KiB
JavaScript

import * as blueslip from "./blueslip";
import * as channel from "./channel";
import * as server_events from "./server_events";
export let next_local_id;
export const messages = new Map();
export function reset_id_state() {
next_local_id = 0;
}
export function get_new_local_id() {
next_local_id += 1;
const local_id = next_local_id;
return "loc-" + local_id.toString();
}
function report_send_time(send_time, receive_time, locally_echoed, rendered_changed) {
const data = {
time: send_time.toString(),
received: receive_time.toString(),
locally_echoed,
};
if (locally_echoed) {
data.rendered_content_disparity = rendered_changed;
}
channel.post({
url: "/json/report/send_times",
data,
});
}
export class MessageState {
start = new Date();
received = undefined;
send_finished = undefined;
rendered_content_disparity = false;
constructor(opts) {
this.local_id = opts.local_id;
this.locally_echoed = opts.locally_echoed;
}
start_resend() {
this.start = new Date();
this.received = undefined;
this.send_finished = undefined;
this.rendered_content_disparity = false;
}
maybe_restart_event_loop() {
if (this.received) {
// We got our event, no need to do anything
return;
}
blueslip.log(
`Restarting get_events due to delayed receipt of sent message ${this.local_id}`,
);
server_events.restart_get_events();
}
maybe_report_send_times() {
if (!this.ready()) {
return;
}
report_send_time(
this.send_finished - this.start,
this.received - this.start,
this.locally_echoed,
this.rendered_content_disparity,
);
}
report_event_received() {
this.received = new Date();
this.maybe_report_send_times();
}
mark_disparity() {
this.rendered_content_disparity = true;
}
report_server_ack() {
this.send_finished = new Date();
this.maybe_report_send_times();
// We only start our timer for events coming in here,
// since it's plausible the server rejected our message,
// or took a while to process it, but there is nothing
// wrong with our event loop.
if (!this.received) {
setTimeout(this.maybe_restart_event_loop.bind(this), 5000);
}
}
ready() {
return this.send_finished !== undefined && this.received !== undefined;
}
}
export function start_tracking_message(opts) {
const local_id = opts.local_id;
if (!opts.local_id) {
blueslip.error("You must supply a local_id");
return;
}
if (messages.has(local_id)) {
blueslip.error("We are re-using a local_id");
return;
}
const state = new MessageState(opts);
messages.set(local_id, state);
}
export function get_message_state(local_id) {
const state = messages.get(local_id);
if (!state) {
blueslip.warn("Unknown local_id: " + local_id);
}
return state;
}
export function mark_disparity(local_id) {
const state = get_message_state(local_id);
if (!state) {
return;
}
state.mark_disparity();
}
export function report_event_received(local_id) {
const state = get_message_state(local_id);
if (!state) {
return;
}
state.report_event_received();
}
export function start_resend(local_id) {
const state = get_message_state(local_id);
if (!state) {
return;
}
state.start_resend();
}
export function report_server_ack(local_id) {
const state = get_message_state(local_id);
if (!state) {
return;
}
state.report_server_ack();
}
export function initialize() {
reset_id_state();
}