| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- // Copyright 2015 The MemDB Authors.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- // implied. See the License for the specific language governing
- // permissions and limitations under the License. See the AUTHORS file
- // for names of contributors.
- 'use strict';
- var P = require('bluebird');
- var _ = require('lodash');
- var should = require('should');
- var memdb = require('../../lib');
- var env = require('../env');
- var logger = require('memdb-logger').getLogger('test', __filename);
- describe('autoconnection test', function(){
- beforeEach(env.flushdb);
- it('concurrent execute', function(cb){
- var shardId = Object.keys(env.config.shards)[0];
- var user1 = {_id : '1', name : 'rain', level : 0};
- var autoconn = null;
- return P.try(function(){
- return env.startCluster(shardId);
- })
- .then(function(){
- return memdb.autoConnect(env.config);
- })
- .then(function(ret){
- autoconn = ret;
- return autoconn.transaction(function(){
- var User = autoconn.collection('user');
- return User.insert(user1);
- }, shardId);
- })
- .then(function(){
- var count = 8;
- var delay = 0;
- return P.map(_.range(count), function(){
- delay += 10;
- return P.delay(delay)
- .then(function(){
- // Simulate non-atomic check and update operation
- // each 'thread' add 1 to user1.level
- return autoconn.transaction(function(){
- var User = autoconn.collection('user');
- var level = null;
- return P.try(function(){
- return User.find(user1._id, 'level');
- })
- .then(function(ret){
- level = ret.level;
- })
- .delay(20)
- .then(function(){
- return User.update(user1._id, {level : level + 1});
- });
- }, shardId);
- });
- })
- .then(function(){
- return autoconn.transaction(function(){
- var User = autoconn.collection('user');
- return P.try(function(){
- return User.find(user1._id);
- })
- .then(function(ret){
- // level should equal to count
- ret.level.should.eql(count);
- return User.remove(user1._id);
- });
- }, shardId);
- });
- })
- .then(function(){
- return autoconn.transaction(function(){
- return P.try(function(){
- var User = autoconn.collection('user');
- return User.insert(user1);
- }).then(function(){
- //Should roll back on exception
- throw new Error('Oops!');
- });
- }, shardId)
- .catch(function(e){
- e.message.should.eql('Oops!');
- });
- })
- .then(function(){
- return autoconn.transaction(function(){
- return P.try(function(){
- var User = autoconn.collection('user');
- return User.find(user1._id);
- })
- .then(function(ret){
- (ret === null).should.eql(true);
- });
- }, shardId);
- })
- .then(function(){
- return autoconn.close();
- })
- .finally(function(){
- return env.stopCluster();
- })
- .nodeify(cb);
- });
- it('autoconnect to multiple shards', function(cb){
- var autoconn = null;
- return P.try(function(){
- return env.startCluster(['s1', 's2']);
- })
- .then(function(){
- return memdb.autoConnect({shards : env.config.shards});
- })
- .then(function(ret){
- autoconn = ret;
- // execute in s1
- return autoconn.transaction(function(){
- var Player = autoconn.collection('player');
- return Player.insert({_id : 'p1', name : 'rain'});
- }, 's1');
- })
- .then(function(){
- // execute in s2
- return autoconn.transaction(function(){
- var Player = autoconn.collection('player');
- return Player.remove('p1');
- }, 's2');
- })
- .then(function(){
- return autoconn.close();
- })
- .finally(function(){
- return env.stopCluster();
- })
- .nodeify(cb);
- });
- it('findReadOnly', function(cb){
- var autoconn = null;
- return P.try(function(){
- return env.startCluster(['s1', 's2']);
- })
- .then(function(){
- return memdb.autoConnect({shards : env.config.shards});
- })
- .then(function(ret){
- autoconn = ret;
- // execute in s1
- return autoconn.transaction(function(){
- return autoconn.collection('player').insert({_id : 'p1', name : 'rain'});
- }, 's1');
- })
- .then(function(){
- // read in s2
- return autoconn.transaction(function(){
- return autoconn.collection('player').findReadOnly('p1')
- .then(function(player){
- player.name.should.eql('rain');
- });
- }, 's2');
- })
- .then(function(){
- // execute in s1
- return autoconn.transaction(function(){
- return autoconn.collection('player').remove('p1');
- }, 's1');
- })
- .then(function(){
- return autoconn.close();
- })
- .finally(function(){
- return env.stopCluster();
- })
- .nodeify(cb);
- });
- });
|