Skip to content

Commit 579c504

Browse files
committed
Added retry script.
1 parent 7f7e27c commit 579c504

File tree

5 files changed

+195
-69
lines changed

5 files changed

+195
-69
lines changed

src/hook.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ var semver = require( "semver" ),
33
UserError = require( "./user-error" ),
44
pluginsDb = require( "./pluginsdb" ),
55
service = require( "./service" ),
6-
retry = require( "./retry" );
6+
retry = require( "./retrydb" );
77

88
function processHook( data, fn ) {
99
var repo = service.getRepoByHook( data );

src/retry.js

Lines changed: 76 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,89 @@
1-
var sqlite = require( "sqlite3" );
2-
3-
var db;
4-
5-
function connect( fn ) {
6-
db = new sqlite.Database( "retry.db", fn );
1+
var Step = require( "step" ),
2+
hook = require( "./hook" ),
3+
service = require( "./service" ),
4+
retry = require( "./retrydb" );
5+
6+
process.on( "uncaughtException", function( error ) {
7+
// TODO: log error to file
8+
console.error( "uncaught exception" );
9+
console.error( error.stack );
10+
});
11+
12+
// exponential backoff for retries, with a max of 2 minutes
13+
function wait( tries ) {
14+
return Math.min( 120, (Math.pow( 2, tries ) - 1) ) * 1000;
715
}
816

9-
function auto( fn ) {
10-
return function() {
11-
var that = this,
12-
args = arguments;
17+
var actions = {};
18+
19+
actions.processVersions = function( repoId, fn ) {
20+
var repo = service.getRepoById( repoId );
21+
hook.processVersions( repo, fn );
22+
};
1323

14-
if ( db ) {
15-
return fn.apply( that, args );
24+
actions.processRelease = function( repoId, tag, fn ) {
25+
var repo = service.getRepoById( repoId );
26+
repo.getRelease( tag, function( error, release ) {
27+
if ( error ) {
28+
return fn( error );
1629
}
1730

18-
connect(function( error ) {
31+
hook.processRelease( repo, release, fn );
32+
});
33+
};
34+
35+
actions.processMeta = function( repoId, fn ) {
36+
var repo = service.getRepoById( repoId );
37+
hook.processMeta( repo, fn );
38+
};
39+
40+
function processFailures( fn ) {
41+
Step(
42+
function() {
43+
retry.getFailure( this );
44+
},
45+
46+
function( error, failure ) {
1947
if ( error ) {
2048
return fn( error );
2149
}
2250

23-
fn.apply( that, args );
24-
});
25-
};
26-
}
51+
// no more failures, wait then try again
52+
if ( !failure ) {
53+
setTimeout(function() {
54+
processFailures( fn );
55+
}, 5000 );
56+
return;
57+
}
2758

28-
module.exports = {
29-
log: auto(function( method ) {
30-
var str, fn,
31-
args = [].slice.call( arguments, 1 );
59+
// TODO: if failure count gets too high, email someone
60+
this.parallel()( null, failure );
61+
setTimeout( this.parallel(), wait( failure.tries ) );
62+
},
3263

33-
if ( typeof args[ args.length - 1 ] === "function" ) {
34-
fn = args.pop();
35-
}
64+
function( error, failure ) {
65+
this.parallel()( null, failure );
66+
actions[ failure.method ].apply( null, failure.args.concat( this.parallel() ) );
67+
},
3668

37-
str = JSON.stringify({
38-
method: method,
39-
args: args
40-
});
41-
42-
db.run( "INSERT OR IGNORE INTO retry( retry ) VALUES( ? )",
43-
[ str ], fn );
44-
}),
45-
46-
_reset: function( fn ) {
47-
var fs = require( "fs" ),
48-
Step = require( "step" );
49-
50-
Step(
51-
function() {
52-
fs.unlink( "retry.db", this );
53-
},
54-
55-
function( error ) {
56-
if ( !error || error.code === "ENOENT" ) {
57-
return connect( this );
58-
}
59-
60-
fn( error );
61-
},
62-
63-
function( error ) {
64-
if ( error ) {
65-
return fn( error );
66-
}
67-
68-
db.run( "CREATE TABLE retry (" +
69-
"retry TEXT PRIMARY KEY, " +
70-
"timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP" +
71-
")", this );
72-
},
73-
74-
function( error ) {
75-
fn( error );
69+
function( error, failure ) {
70+
if ( error ) {
71+
return fn( error );
7672
}
77-
);
78-
}
79-
};
73+
74+
retry.remove( failure.retry, this );
75+
},
76+
77+
function( error ) {
78+
if ( error ) {
79+
console.log( error.stack );
80+
}
81+
82+
processFailures( fn );
83+
}
84+
);
85+
}
86+
87+
processFailures(function( error ) {
88+
console.error( error.stack );
89+
});

src/retrydb.js

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
var sqlite = require( "sqlite3" );
2+
3+
var db;
4+
5+
function connect( fn ) {
6+
db = new sqlite.Database( "retry.db", fn );
7+
}
8+
9+
function auto( fn ) {
10+
return function() {
11+
var that = this,
12+
args = arguments;
13+
14+
if ( db ) {
15+
return fn.apply( that, args );
16+
}
17+
18+
connect(function( error ) {
19+
if ( error ) {
20+
return fn( error );
21+
}
22+
23+
fn.apply( that, args );
24+
});
25+
};
26+
}
27+
28+
module.exports = {
29+
log: auto(function( method ) {
30+
var str,
31+
fn = function() {},
32+
args = [].slice.call( arguments, 1 );
33+
34+
if ( typeof args[ args.length - 1 ] === "function" ) {
35+
fn = args.pop();
36+
}
37+
38+
str = JSON.stringify({
39+
method: method,
40+
args: args
41+
});
42+
43+
db.run( "INSERT INTO retry( retry ) VALUES( ? )", [ str ], function( error ) {
44+
if ( !error ) {
45+
return fn( null );
46+
}
47+
48+
if ( error.code === "SQLITE_CONSTRAINT" ) {
49+
return db.run( "UPDATE retry SET tries = tries + 1 WHERE retry = ?",
50+
[ str ], fn );
51+
}
52+
53+
fn( error );
54+
});
55+
}),
56+
57+
getFailure: auto(function( fn ) {
58+
db.get( "SELECT * FROM retry ORDER BY timestamp ASC LIMIT 1",
59+
function( error, row ) {
60+
if ( error ) {
61+
return fn( error );
62+
}
63+
64+
if ( !row ) {
65+
return fn( null, null );
66+
}
67+
68+
var data = JSON.parse( row.retry );
69+
fn( null, {
70+
method: data.method,
71+
args: data.args,
72+
timestamp: row.timestamp,
73+
tries: row.tries,
74+
retry: row.retry
75+
});
76+
});
77+
}),
78+
79+
remove: auto(function( retry, fn ) {
80+
db.run( "DELETE FROM retry WHERE retry = ?", [ retry ], fn );
81+
}),
82+
83+
_reset: function( fn ) {
84+
var fs = require( "fs" ),
85+
Step = require( "step" );
86+
87+
Step(
88+
function() {
89+
fs.unlink( "retry.db", this );
90+
},
91+
92+
function( error ) {
93+
if ( !error || error.code === "ENOENT" ) {
94+
return connect( this );
95+
}
96+
97+
fn( error );
98+
},
99+
100+
function( error ) {
101+
if ( error ) {
102+
return fn( error );
103+
}
104+
105+
db.run( "CREATE TABLE retry (" +
106+
"retry TEXT PRIMARY KEY, " +
107+
"timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, " +
108+
"tries INTEGER DEFAULT 0" +
109+
")", this );
110+
},
111+
112+
function( error ) {
113+
fn( error );
114+
}
115+
);
116+
}
117+
};

src/setup.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ var Step = require( "step" ),
22
rimraf = require( "rimraf" ),
33
pluginsDb = require( "./pluginsdb" ),
44
wordpress = require( "./wordpress" ),
5-
retry = require( "./retry" ),
5+
retry = require( "./retrydb" ),
66
config = require( "./config" );
77

88
Step(

src/update.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ var hook = require( "./hook" );
33
process.on( "uncaughtException", function( error ) {
44
// TODO: log error to file
55
console.error( "uncaught exception" );
6-
console.error( error );
76
console.error( error.stack );
87
});
98

0 commit comments

Comments
 (0)