diff --git a/lib/scripto.js b/lib/scripto.js index d4a973a..97bc60b 100644 --- a/lib/scripto.js +++ b/lib/scripto.js @@ -29,10 +29,27 @@ function Scripto (redisClient) { this.run = function run(scriptName, keys, args, callback) { - if(scripts[scriptName]) { + if(scripts[scriptName]) { if(scriptShas[scriptName]) { var sha = scriptShas[scriptName]; - evalShaScript(redisClient, sha, keys, args, callback); + evalShaScript(redisClient, sha, keys, args, function(err, result) { + if(err && isScriptNotLoadedError(err)) { + /** + * The script was once loaded but is no longer loaded. + * We may have switched redis instances using sentinel + */ + loadScriptIntoRedis(redisClient, scripts[scriptName], function(err, sha) { + if(err) return callback(err); + + scriptShas[scriptName] = sha; + evalShaScript(redisClient, sha, keys, args, callback); + }); + + return; + } + + callback(err, result); + }); } else { var script = scripts[scriptName]; evalScript(redisClient, script, keys, args, callback); @@ -125,7 +142,7 @@ function loadScriptsIntoRedis (redisClient, scripts, callback) { if(cnt < keys.length) { var key = keys[cnt++]; - redisClient.send_command('script', ['load', scripts[key]], function(err, sha) { + loadScriptIntoRedis(redisClient, scripts[key], function(err, sha) { if(err) { callback(err); @@ -141,6 +158,14 @@ function loadScriptsIntoRedis (redisClient, scripts, callback) { })(); } +function isScriptNotLoadedError(err) { + return err.message && err.message.indexOf('NOSCRIPT No matching script') === 0; +} + +function loadScriptIntoRedis(redisClient, script, callback) { + redisClient.send_command('script', ['load', script], callback); +} + function evalScript(redisClient, script, keys, args, callback) { var keysLength= keys.length || 0; diff --git a/test/scripto.js b/test/scripto.js index 9efde23..6ab3608 100644 --- a/test/scripto.js +++ b/test/scripto.js @@ -130,6 +130,21 @@ suite('Scripto', function() { })); + test('reload a script if its no longer in the script cache', _clean(function(done) { + + var s = new Scripto(redisClient); + s.loadFromFile('read-write', path.resolve(scriptDir, 'read-write.lua')); + redisClient.script('flush', function() { + s.run('read-write', ['helloKey'], [200], function(err, result) { + + assert.equal(err, null); + assert.equal(result, 200); + done(); + }); + }); + + })); + }); function _clean(callback) {