<commit_before>var Backbone = require("lib").Backbone;
var _ = require("lib")._;


var UserModel = Backbone.Model.extend({

    defaults: {
        isAnonymous: true
    },

    url: function() {
        return "/api/v1/user/"
    },

    isAuthenticated: function() {
        return !this.attributes.isAnonymous;
    },

    logout: function() {
        this.url = "/api/v1/user/logout/";
        return this.save();
    }
});

var StreamSaveModel = Backbone.Model.extend({

    MAX_REQUESTS_PER_SECOND: 1,

    initialize: function() {
        
        //this._triggerIsSavedChanged = _.debounce(this._triggerIsSavedChanged, 1000, {immedate: false});

        this._lastRequestId = 0;
        this._lastSavedRequestId = 0;
        this._isSaved = true;

        this._saveImpl = _.throttle(this._saveImpl, 1000 / this.MAX_REQUESTS_PER_SECOND);
    },

    save: function() {

        if(this.isSaved()) {
            console.info("saving", this._lastRequestId);
            this._lastRequestId += 1;
            this._saveImpl();
        }
        else {
            console.info("inc requestId, don't save now");
            this._lastRequestId += 1;
        }
        this._updateIsSaved();

    },

    _saveImpl: function() {

        var requestId = this._lastRequestId;  
        var self = this; 
        var callback = function() {
            console.info("Saved: ", requestId);
            self._lastSavedRequestId = requestId;
            self._updateIsSaved();
            if(!self.isSaved()) {
                console.info("saving ", self._lastRequestId);
                self._saveImpl();
            }
        };
        Backbone.Model.prototype.save.apply(this, arguments).then(callback);
    },

    isSaved: function() {
        return this._lastSavedRequestId == this._lastRequestId;
    },

    _updateIsSaved: function() {
        var previousStatus, currentStatus;
        previousStatus = this._isSaved;
        currentStatus = this.isSaved();
        this._isSaved = currentStatus;

        if(previousStatus !== currentStatus) {
            this._triggerIsSavedChanged();
        }
    },

    _triggerIsSavedChanged: function() {
        console.info("isSaved changed", this._isSaved);
        this.trigger("change:isSaved", this._isSaved);
    }
});


MAX_RETRIES = 2;
BACKOFF_PER_RETRY = 1000; 

var originalFetch = Backbone.Model.prototype.fetch; 

fetchWithRetries = function() {
    var self = this;

    if(_.isUndefined(self._retries)) {
        self._retries = 0;
        self._fetchPromise = $.Deferred();
    }

    var onError = function(model, response) {
        self._retries += 1;
        if(self._retries > MAX_RETRIES || response.status === 404) {
            var promise = self._fetchPromise;
            delete self._retries;
            delete self._fetchPromise;
            promise.reject();
            return;
        }

        setTimeout(function() {
            fetchWithRetries.call(self);
        }, self._retries * 1000);
    }<commit_msg>Client retry GET requests: Set interval between retries to 2 seconds.<commit_after>var Backbone = require("lib").Backbone;
var _ = require("lib")._;


var UserModel = Backbone.Model.extend({

    defaults: {
        isAnonymous: true
    },

    url: function() {
        return "/api/v1/user/"
    },

    isAuthenticated: function() {
        return !this.attributes.isAnonymous;
    },

    logout: function() {
        this.url = "/api/v1/user/logout/";
        return this.save();
    }
});

var StreamSaveModel = Backbone.Model.extend({

    MAX_REQUESTS_PER_SECOND: 1,

    initialize: function() {
        
        //this._triggerIsSavedChanged = _.debounce(this._triggerIsSavedChanged, 1000, {immedate: false});

        this._lastRequestId = 0;
        this._lastSavedRequestId = 0;
        this._isSaved = true;

        this._saveImpl = _.throttle(this._saveImpl, 1000 / this.MAX_REQUESTS_PER_SECOND);
    },

    save: function() {

        if(this.isSaved()) {
            console.info("saving", this._lastRequestId);
            this._lastRequestId += 1;
            this._saveImpl();
        }
        else {
            console.info("inc requestId, don't save now");
            this._lastRequestId += 1;
        }
        this._updateIsSaved();

    },

    _saveImpl: function() {

        var requestId = this._lastRequestId;  
        var self = this; 
        var callback = function() {
            console.info("Saved: ", requestId);
            self._lastSavedRequestId = requestId;
            self._updateIsSaved();
            if(!self.isSaved()) {
                console.info("saving ", self._lastRequestId);
                self._saveImpl();
            }
        };
        Backbone.Model.prototype.save.apply(this, arguments).then(callback);
    },

    isSaved: function() {
        return this._lastSavedRequestId == this._lastRequestId;
    },

    _updateIsSaved: function() {
        var previousStatus, currentStatus;
        previousStatus = this._isSaved;
        currentStatus = this.isSaved();
        this._isSaved = currentStatus;

        if(previousStatus !== currentStatus) {
            this._triggerIsSavedChanged();
        }
    },

    _triggerIsSavedChanged: function() {
        console.info("isSaved changed", this._isSaved);
        this.trigger("change:isSaved", this._isSaved);
    }
});


MAX_RETRIES = 2;
BACKOFF_PER_RETRY = 2000; 

var originalFetch = Backbone.Model.prototype.fetch; 

fetchWithRetries = function() {
    var self = this;

    if(_.isUndefined(self._retries)) {
        self._retries = 0;
        self._fetchPromise = $.Deferred();
    }

    var onError = function(model, response) {
        self._retries += 1;
        if(self._retries > MAX_RETRIES || response.status === 404) {
            var promise = self._fetchPromise;
            delete self._retries;
            delete self._fetchPromise;
            promise.reject();
            return;
        }

        //todo -> implement clearTimeout during cleanup
        setTimeout(function() {
            fetchWithRetries.call(self);
        }, self._retries * 1000);
    }
{'fraction_non_alphanumeric': 0.12348509662626925, 'fraction_numerical': 0.009662626924336719, 'mean_word_length': 2.070387129210659, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4597987', 'n_tokens_mistral': 1883, 'n_tokens_neox': 1768, 'n_words': 319}