Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Handle Posterous API rate-limit automatically #4

Merged
merged 5 commits into from

2 participants

Ben Hughes andzdroid
Ben Hughes

I found out the hard way that Posterous rate-limits API calls to 1/sec. This change (although a bit naive) ensures that we don't exceed that. It should be completely backwards compatible - there's a new parameter on the constructor that turns the functionality on.

I also changed the JSON parse error handling, as r.error never seems to be set, and as a result 403s from Posterous were being swallowed.

I haven't run the rest suite as it seems to still be using the old auth method (ie not supplying an auth token).

andzdroid andzdroid merged commit 6d48b49 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 44 additions and 19 deletions.
  1. +43 −18 lib/posterous.js
  2. +1 −1  package.json
61 lib/posterous.js
View
@@ -5,10 +5,16 @@ var api = require('./api');
var HOST = 'posterous.com';
var PATH = '/api/2/';
+var lastCallMade = Date.now() - 1000;
-var Posterous = function(user, pass, api_token) {
+// Unfortunately Posterous rate-limites API calls to 1/sec. Passing
+// forceSynchronous = true will ensure that the calls comply with this limit.
+// If you do not set forceSynchronous, you will need to manage the rate limit
+// yourself
+var Posterous = function(user, pass, api_token, forceSynchronous) {
this._auth = 'Basic ' + new Buffer(user + ':' + pass).toString('base64');
this._token = api_token;
+ this._synchronous = forceSynchronous;
};
@@ -44,7 +50,6 @@ Posterous.prototype.request = function(method, api, args, callback) {
headers: headers
};
- console.log('uri path: ' + reqOptions.path);
//Make request to Posterous API
var req = http.request(reqOptions, function apiRequest(res) {
//Gather response
@@ -57,16 +62,14 @@ Posterous.prototype.request = function(method, api, args, callback) {
//Work-around, not all API responses are valid json >_>
//Example: Deleting a site gives a response of 'undefined:1'
try {
- var r = JSON.parse(response);
-
- if (r.error) {
- return callback(r.message || r.error);
- }
-
- callback(null, r);
+ var r = JSON.parse(response);
} catch (err) {
- callback(null, {});
+ var message = 'Error parsing JSON: ' + err + ' in\n' + response;
+ return callback(message, null);
}
+
+ callback(null, r);
+
});
});
@@ -81,8 +84,24 @@ Posterous.prototype.request = function(method, api, args, callback) {
req.end();
};
-Posterous.prototype.makeRequest = function(method, args) {
-console.log('in makeRequest trying');
+Posterous.prototype.makeRequestSync = function(method, args){
+ var gap = Date.now() - lastCallMade;
+ console.log(gap + ' ms since last execution completed');
+
+ if(this._synchronous && gap < 1000){
+ console.log('sleeping');
+ var that = this;
+ setTimeout(function(){that.makeRequestSync(method, args)}, 1000);
+ }
+ else{
+ lastCallMade = Date.now();
+ this.makeRequest(method, args, function(){
+ lastCallMade = Date.now();
+ });
+ }
+}
+
+Posterous.prototype.makeRequest = function(method, args, cbk) {
if (args.length < 3) {
return console.error('[Posterous] You must pass arguments to the method.');
}
@@ -123,25 +142,31 @@ console.log('in makeRequest trying');
//console.log(method + ' ' + path);
- this.request(method, path, options, callback);
+ this.request(method, path, options, function(err, result){
+ if(typeof cbk === 'function')
+ cbk();
+
+ callback(err, result);
+ });
+
+
};
Posterous.prototype.get = function() {
- console.log('about to get');
- this.makeRequest('GET', arguments);
+ this.makeRequestSync('GET', arguments);
};
Posterous.prototype.post = function() {
- this.makeRequest('POST', arguments);
+ this.makeRequestSync('POST', arguments);
};
Posterous.prototype.put = function() {
- this.makeRequest('PUT', arguments);
+ this.makeRequestSync('PUT', arguments);
};
Posterous.prototype.del = Posterous.prototype.delete = function() {
- this.makeRequest('DELETE', arguments);
+ this.makeRequestSync('DELETE', arguments);
};
module.exports = Posterous;
2  package.json
View
@@ -4,7 +4,7 @@
"description": "Package for the Posterous API",
"keywords": [
"posterous",
- "api",
+ "api"
],
"contributors": [
{
Something went wrong with that request. Please try again.