mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-31 03:53:50 +00:00 
			
		
		
		
	sending messages: Extract sent_messages.js.
This commit extract send_messages.js to clean up code related
to the following things:
    * sending data to /json/report_send_time
    * restarting the event loop if events don't arrive on time
The code related to /json/report changes the following ways:
    * We track the state almost completely in the new
      send_messages.js module, with other modules just
      making one-line calls.
    * We no longer send "displayed" times to the servers, since
      we were kind of lying about them anyway.
    * We now explicitly track the state of each single sent
      message in its own object.
    * We now look up data related to the messages by local_id,
      instead of message_id.  The problem with message_id was
      that is was mutable.  Now we use local_id, and we extend
      the local_id concept to messages that don't get rendered
      client side.  We no longer need to react to the
      'message_id_changed' event to change our hash key.
    * The code used to live in many places:
        * various big chunks were scattered among compose.js,
          and those were all moved or reduced to one-line
          calls into the new module
        * echo.js continues to make basically one-line calls,
          but it no longer calls compose.report_as_received(),
          nor does it set the "start" time.
        * message_util.js used to report received events, but
          only when they finally got drawn in the home view;
          this code is gone now
The code related to restarting the event loop if events don't arrive
changes as follows:
    * The timer now gets set up from within
      send_messages.message_state.report_server_ack,
      where we can easily inspect the current state of the
      possibly-still-in-flight message.
    * The code to confirm that an event was received happens now
      in server_events.js, rather than later, so that we don't
      falsely blame the event loop  for a downstream bug.  (Plus
      it's easier to just do it one place.)
This change removes a fair amount of code from our node tests.  Some
of the removal is good stuff related to us completing killing off
unnecessary code.  Other removals are more expediency-driven, and
we should make another sweep at ramping up our coverage on compose.js,
with possibly a little more mocking of the new `send_messages` code
layer, since it's now abstracted better.
There is also some minor cleanup to echo.resend_message() in this
commit.
See #5968 for a detailed breakdown of the changes.
			
			
This commit is contained in:
		
							
								
								
									
										184
									
								
								static/js/sent_messages.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								static/js/sent_messages.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| var sent_messages = (function () { | ||||
|  | ||||
| var exports = {}; | ||||
|  | ||||
| exports.messages = {}; | ||||
|  | ||||
| exports.reset_id_state = function () { | ||||
|     exports.next_local_id = 0; | ||||
| }; | ||||
|  | ||||
| exports.get_new_local_id = function () { | ||||
|     exports.next_local_id += 1; | ||||
|     var local_id = exports.next_local_id; | ||||
|     return 'loc-' + local_id.toString(); | ||||
| }; | ||||
|  | ||||
| function report_send_time(send_time, receive_time, | ||||
|                           locally_echoed, rendered_changed) { | ||||
|     var data = { | ||||
|         time: send_time.toString(), | ||||
|         received: receive_time.toString(), | ||||
|         locally_echoed: locally_echoed, | ||||
|     }; | ||||
|  | ||||
|     if (locally_echoed) { | ||||
|         data.rendered_content_disparity = rendered_changed; | ||||
|     } | ||||
|  | ||||
|     channel.post({ | ||||
|         url: '/json/report_send_time', | ||||
|         data: data, | ||||
|     }); | ||||
| } | ||||
|  | ||||
| exports.start_tracking_message = function (opts) { | ||||
|     var local_id = opts.local_id; | ||||
|  | ||||
|     if (!opts.local_id) { | ||||
|         blueslip.error('You must supply a local_id'); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (exports.messages[local_id] !== undefined) { | ||||
|         blueslip.error('We are re-using a local_id'); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     var state = exports.message_state(opts); | ||||
|  | ||||
|     exports.messages[local_id] = state; | ||||
| }; | ||||
|  | ||||
| exports.message_state = function (opts) { | ||||
|     var self = {}; | ||||
|     self.data = {}; | ||||
|  | ||||
|     self.data.start = new Date(); | ||||
|  | ||||
|     self.data.local_id = opts.local_id; | ||||
|     self.data.locally_echoed = opts.locally_echoed; | ||||
|  | ||||
|  | ||||
|     self.data.received = undefined; | ||||
|     self.data.send_finished = undefined; | ||||
|     self.data.rendered_content_disparity = false; | ||||
|  | ||||
|     self.start_resend = function () { | ||||
|         self.data.start = new Date(); | ||||
|         self.data.received = undefined; | ||||
|         self.data.send_finished = undefined; | ||||
|         self.data.rendered_content_disparity = false; | ||||
|     }; | ||||
|  | ||||
|     self.maybe_restart_event_loop = function () { | ||||
|         if (self.data.received) { | ||||
|             // We got our event, no need to do anything | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         blueslip.log("Restarting get_events due to " + | ||||
|                      "delayed receipt of sent message " + | ||||
|                      self.data.local_id); | ||||
|  | ||||
|         server_events.restart_get_events(); | ||||
|     }; | ||||
|  | ||||
|     self.maybe_report_send_times = function () { | ||||
|         if (!self.ready()) { | ||||
|             return; | ||||
|         } | ||||
|         var data = self.data; | ||||
|         report_send_time(data.send_finished - data.start, | ||||
|                          data.received - data.start, | ||||
|                          data.locally_echoed, | ||||
|                          data.rendered_content_disparity); | ||||
|     }; | ||||
|  | ||||
|     self.report_event_received = function () { | ||||
|         self.data.received = new Date(); | ||||
|         self.maybe_report_send_times(); | ||||
|     }; | ||||
|  | ||||
|     self.mark_disparity = function () { | ||||
|         self.data.rendered_content_disparity = true; | ||||
|     }; | ||||
|  | ||||
|     self.report_server_ack = function () { | ||||
|         self.data.send_finished = new Date(); | ||||
|         self.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 (!self.data.received) { | ||||
|             setTimeout(self.maybe_restart_event_loop, 5000); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     self.ready = function () { | ||||
|         return (self.data.send_finished !== undefined) && | ||||
|                (self.data.received !== undefined); | ||||
|     }; | ||||
|  | ||||
|     return self; | ||||
| }; | ||||
|  | ||||
| exports.get_message_state = function (local_id) { | ||||
|     var state = exports.messages[local_id]; | ||||
|  | ||||
|     if (!state) { | ||||
|         blueslip.warn('Unknown local_id: ' + local_id); | ||||
|     } | ||||
|  | ||||
|     return state; | ||||
| }; | ||||
|  | ||||
|  | ||||
| exports.mark_disparity = function (local_id) { | ||||
|     var state = exports.get_message_state(local_id); | ||||
|     if (!state) { | ||||
|         return; | ||||
|     } | ||||
|     state.mark_disparity(); | ||||
| }; | ||||
|  | ||||
| exports.report_event_received = function (local_id) { | ||||
|     var state = exports.get_message_state(local_id); | ||||
|     if (!state) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     state.report_event_received(); | ||||
| }; | ||||
|  | ||||
| exports.start_resend = function (local_id) { | ||||
|     var state = exports.get_message_state(local_id); | ||||
|     if (!state) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     state.start_resend(); | ||||
| }; | ||||
|  | ||||
| exports.report_server_ack = function (local_id) { | ||||
|     var state = exports.get_message_state(local_id); | ||||
|     if (!state) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     state.report_server_ack(); | ||||
| }; | ||||
|  | ||||
| exports.initialize = function () { | ||||
|     exports.reset_id_state(); | ||||
| }; | ||||
|  | ||||
| return exports; | ||||
|  | ||||
| }()); | ||||
| if (typeof module !== 'undefined') { | ||||
|     module.exports = sent_messages; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user