diff --git a/templates/zephyr/index.html b/templates/zephyr/index.html
index ac65b1f752..3c0d909cd9 100644
--- a/templates/zephyr/index.html
+++ b/templates/zephyr/index.html
@@ -50,6 +50,7 @@
{# Not escaped, because it's guaranteed by the model to be an integer. #}
var initial_pointer = {{ user_profile.pointer }};
+var server_generation = {{ server_generation }};
var email = "{{ user_profile.user.email|escapejs }}";
var have_initial_messages = {{ have_initial_messages|escapejs }};
diff --git a/tools/jslint/check-all.js b/tools/jslint/check-all.js
index 4c8113fbf4..04e6c75da8 100644
--- a/tools/jslint/check-all.js
+++ b/tools/jslint/check-all.js
@@ -7,6 +7,7 @@ var globals =
// index.html
+ ' initial_pointer email stream_list people_list have_initial_messages'
+ + ' server_generation'
// compose.js
+ ' show_compose hide_compose toggle_compose clear_compose_box compose_button'
diff --git a/zephyr/static/js/zephyr.js b/zephyr/static/js/zephyr.js
index eea4dfd053..b062495e19 100644
--- a/zephyr/static/js/zephyr.js
+++ b/zephyr/static/js/zephyr.js
@@ -57,9 +57,12 @@ var selected_message; // = get_message_row(selected_message_id)
var received = {
first: -1,
last: -1,
- failures: 0
+ failures: 0,
+ server_generation: -1 /* to be filled in on document.ready */
};
+$(function () { received.server_generation = server_generation; });
+
// The "message groups", i.e. blocks of messages collapsed by recipient.
// Each message table has a list of lists.
var message_groups = {
diff --git a/zephyr/views.py b/zephyr/views.py
index 85084394f3..a416a9afbf 100644
--- a/zephyr/views.py
+++ b/zephyr/views.py
@@ -28,6 +28,9 @@ import socket
import re
import hashlib
import urllib
+import time
+
+SERVER_GENERATION = int(time.time())
def require_post(view_func):
def _wrapped_view_func(request, *args, **kwargs):
@@ -174,7 +177,8 @@ def home(request):
'have_initial_messages':
'true' if num_messages > 0 else 'false',
'show_debug':
- settings.DEBUG and ('show_debug' in request.GET) },
+ settings.DEBUG and ('show_debug' in request.GET),
+ 'server_generation': SERVER_GENERATION},
context_instance=RequestContext(request))
@login_required
@@ -203,12 +207,14 @@ def format_updates_response(messages, mit_sync_bot=False, apply_markdown=False,
return {'messages': [message.to_dict(apply_markdown) for message in messages],
"result": "success",
"msg": "",
- 'where': where}
+ 'where': where,
+ 'server_generation': SERVER_GENERATION}
def return_messages_immediately(request, handler, user_profile, **kwargs):
first = request.POST.get("first")
last = request.POST.get("last")
failures = request.POST.get("failures")
+ client_server_generation = request.POST.get("server_generation")
if first is None or last is None:
# When an API user is first querying the server to subscribe,
# there's no reason to reply immediately.
@@ -251,6 +257,12 @@ def return_messages_immediately(request, handler, user_profile, **kwargs):
handler.finish(format_updates_response([], where="bottom", **kwargs))
return True
+ if client_server_generation is not None and int(client_server_generation) != SERVER_GENERATION:
+ # No messages, but still return immediately to inform the
+ # client that they should reload
+ handler.finish(format_updates_response([], where="bottom", **kwargs))
+ return True
+
return False
def get_updates_backend(request, user_profile, handler, **kwargs):