From 507f32ecff195a9c2701e563d10d77a61fd62a64 Mon Sep 17 00:00:00 2001 From: Stian Eikeland Date: Thu, 2 Oct 2014 17:52:40 +0200 Subject: [PATCH] watcher resyncs on cleared index, ref #31 --- src/watcher.coffee | 10 +++++++++- test/watcher.coffee | 47 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/watcher.coffee b/src/watcher.coffee index de6f17f..3f18de9 100644 --- a/src/watcher.coffee +++ b/src/watcher.coffee @@ -59,10 +59,18 @@ class Watcher extends EventEmitter @emit 'error', error @_retry() + _resync: (err) => + @index = err.error.index + @retryAttempts = 0 + @emit 'resync', err + @_watch() + _respHandler: (err, val, headers) => return if @stopped - if err + if err?.errorCode is 401 and err.error?.index? + @_resync err + else if err @_error err else if headers?['x-etcd-index']? and not val? @_missingValue headers diff --git a/test/watcher.coffee b/test/watcher.coffee index 542380c..5b30b59 100644 --- a/test/watcher.coffee +++ b/test/watcher.coffee @@ -1,4 +1,7 @@ -require 'should' +should = require 'should' +nock = require 'nock' + +Etcd = require '../src/index' Watcher = require '../src/watcher.coffee' class FakeEtcd @@ -121,3 +124,45 @@ describe 'Watcher', -> w.stop() +describe 'Watcher resync', -> + + getNock = -> + nock 'http://127.0.0.1:4001' + + it 'should resync if index is outdated and cleared', (done) -> + # getNock() + # .get('/v2/keys/key') + # .reply(200, {}) + + getNock() + .get('/v2/keys/key?waitIndex=0&wait=true') + .reply(401, { + errorCode: 401, + message: "The event in requested index is outdated and cleared", + cause: "the requested history has been cleared [1007/4]", + index: 2006 + }) + .get('/v2/keys/key?waitIndex=2006&wait=true') + .reply(200, { + action:"set", + node: { + key: "/key", + value: "banan", + modifiedIndex: 2013, + createdIndex: 2013 + }, + prevNode: { + key: "/key", + value: "2", + modifiedIndex: 5, + createdIndex: 5 + } + }) + + etcd = new Etcd + w = etcd.watcher 'key', 0 + w.on 'change', (res) -> + res.node.value.should.equal 'banan' + done() + + it 'should discover if it missed any updates on resync'