Per-RPC retry support, used when subscribe() can't find an active instance.
This commit is contained in:
9
api.py
9
api.py
@@ -27,10 +27,6 @@ from cosmopolite.lib import utils
|
|||||||
import config
|
import config
|
||||||
|
|
||||||
|
|
||||||
class InvalidInstanceID(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def CreateChannel(google_user, client, instance_id, args):
|
def CreateChannel(google_user, client, instance_id, args):
|
||||||
models.Instance.FindOrCreate(instance_id)
|
models.Instance.FindOrCreate(instance_id)
|
||||||
|
|
||||||
@@ -84,7 +80,10 @@ def SendMessage(google_user, client, instance_id, args):
|
|||||||
def Subscribe(google_user, client, instance_id, args):
|
def Subscribe(google_user, client, instance_id, args):
|
||||||
instance = models.Instance.FromID(instance_id)
|
instance = models.Instance.FromID(instance_id)
|
||||||
if not instance or not instance.active:
|
if not instance or not instance.active:
|
||||||
raise InvalidInstanceID
|
# Probably a race with the channel opening
|
||||||
|
return {
|
||||||
|
'result': 'retry',
|
||||||
|
}
|
||||||
|
|
||||||
subject = models.Subject.FindOrCreate(args['subject'])
|
subject = models.Subject.FindOrCreate(args['subject'])
|
||||||
messages = args.get('messages', 0)
|
messages = args.get('messages', 0)
|
||||||
|
|||||||
@@ -469,7 +469,7 @@ Cosmopolite.prototype.sendRPCs_ = function(commands, delay) {
|
|||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.responseType = 'json';
|
xhr.responseType = 'json';
|
||||||
|
|
||||||
var retryAfterDelay = function() {
|
var retryAfterDelay = function(newCommands) {
|
||||||
var intDelay =
|
var intDelay =
|
||||||
xhr.getResponseHeader('Retry-After') ||
|
xhr.getResponseHeader('Retry-After') ||
|
||||||
Math.min(32, Math.max(2, delay || 2));
|
Math.min(32, Math.max(2, delay || 2));
|
||||||
@@ -477,14 +477,14 @@ Cosmopolite.prototype.sendRPCs_ = function(commands, delay) {
|
|||||||
this.loggingPrefix_(),
|
this.loggingPrefix_(),
|
||||||
'RPC failed; will retry in ' + intDelay + ' seconds');
|
'RPC failed; will retry in ' + intDelay + ' seconds');
|
||||||
var retry = function() {
|
var retry = function() {
|
||||||
this.sendRPCs_(commands, Math.pow(intDelay, 2));
|
this.sendRPCs_(newCommands, Math.pow(intDelay, 2));
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
window.setTimeout(retry, intDelay * 1000);
|
window.setTimeout(retry, intDelay * 1000);
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
xhr.addEventListener('load', function(e) {
|
xhr.addEventListener('load', function(e) {
|
||||||
if (xhr.status != 200) {
|
if (xhr.status != 200) {
|
||||||
retryAfterDelay();
|
retryAfterDelay(commands);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var data = xhr.response;
|
var data = xhr.response;
|
||||||
@@ -517,11 +517,22 @@ Cosmopolite.prototype.sendRPCs_ = function(commands, delay) {
|
|||||||
// data.
|
// data.
|
||||||
data['events'].forEach(this.onServerEvent_, this);
|
data['events'].forEach(this.onServerEvent_, this);
|
||||||
|
|
||||||
|
var retryCommands = [];
|
||||||
|
|
||||||
for (var i = 0; i < data['responses'].length; i++) {
|
for (var i = 0; i < data['responses'].length; i++) {
|
||||||
|
var response = data['responses'][i];
|
||||||
|
if (response['result'] == 'retry') {
|
||||||
|
retryCommands.push(commands[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (commands[i]['onSuccess']) {
|
if (commands[i]['onSuccess']) {
|
||||||
commands[i]['onSuccess'].bind(this)(data['responses'][i]);
|
commands[i]['onSuccess'].bind(this)(data['responses'][i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (retryCommands.length) {
|
||||||
|
retryAfterDelay(retryCommands);
|
||||||
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
xhr.addEventListener('error', retryAfterDelay);
|
xhr.addEventListener('error', retryAfterDelay);
|
||||||
|
|||||||
Reference in New Issue
Block a user