Просмотр исходного кода

Ignore different order of results from smembers

James Allen 10 лет назад
Родитель
Сommit
59883023ca

+ 7 - 3
services/document-updater/app/coffee/RedisBackend.coffee

@@ -102,7 +102,7 @@ class MultiClient
 			if error?
 				logger.error {err: error}, "error in redis backend"
 			else
-				compareResults(results)
+				compareResults(results, "exec")
 			callback(primaryError, primaryResult)
 
 COMMANDS = {
@@ -153,7 +153,7 @@ for command, key_pos of COMMANDS
 				if error?
 					logger.error {err: error}, "error in redis backend"
 				else
-					compareResults(results)
+					compareResults(results, command)
 				callback(primaryError, primaryResult...)
 
 		MultiClient.prototype[command] = (args...) ->
@@ -164,10 +164,14 @@ for command, key_pos of COMMANDS
 				args_with_key[key_pos] = key
 				client.rclient[command] args_with_key...
 
-compareResults = (results) ->
+compareResults = (results, command) ->
 	return if results.length < 2
 	first = results[0]
+	if command == "smembers"
+		first = first.slice().sort()
 	for result in results.slice(1)
+		if command == "smembers"
+			result = result.slice().sort()
 		if not _.isEqual(first, result)
 			logger.error results: results, "redis backend conflict"
 			Metrics.inc "backend-conflict"

+ 19 - 0
services/document-updater/test/unit/coffee/RedisBackend/RedisBackendTests.coffee

@@ -66,6 +66,7 @@ describe "RedisBackend", ->
 		@client = @RedisBackend.createClient()
 		
 		@doc_id = "mock-doc-id"
+		@project_id = "mock-project-id"
 	
 	it "should create a redis client", ->
 		@redis.createClient
@@ -138,6 +139,24 @@ describe "RedisBackend", ->
 					.calledWith("backend-conflict")
 					.should.equal true
 
+		describe "with differently ordered results from smembers", ->
+			beforeEach (done) ->
+				@rclient_redis.smembers = sinon.stub()
+				@rclient_redis.smembers.withArgs("DocsIn:#{@project_id}").yields(null, ["one", "two"])
+				@rclient_ioredis.smembers = sinon.stub()
+				@rclient_ioredis.smembers.withArgs("DocsIn:{#{@project_id}}").yields(null, ["two", "one"])
+				@client.smembers RedisKeyBuilder.docsInProject({project_id: @project_id}), (error, @result) =>
+					setTimeout () -> # Let all background requests complete
+						done(error)
+			
+			it "should return the primary result", ->
+				@result.should.deep.equal ["one", "two"]
+			
+			it "should send a metric indicating a match", ->
+				@Metrics.inc
+					.calledWith("backend-match")
+					.should.equal true
+
 		describe "when the secondary errors", ->
 			beforeEach (done) ->
 				@rclient_redis.get = sinon.stub()