Sometimes querying view with 'stale: false' not triggering changes


#1

Based on our application logic, I have part of code, responsible to ‘fixing’ changes in view and making them available for all.
To do it, I just querying view with parameters {stale: false}.

/*adding new records into database*/ var document = config.get('database:views:default_document'); var viewName = config.get('database:views:transactions'); var view = parent.database.view(document, viewName, {limit: 1, stale: false}); view.query(function (err) { if(err) { parent.log.error('Error during fixing view: %s', err); } callback(err); });

I expecting that this call will return initiate indexing and return when it done so any other sequential calls to same view will return increased(or decreased if removing) quantity of records.

Problem is that this sometimes working and sometimes - not. E.g. before ‘fixing’ I have 6 records in database, after update it should be 7. Sometimes I receiving 7, sometime 6.

What is wrong?

Server version: 2.5.1


#2

In order to read your own write within a view the call to update the view, needs to have a callback, and from within that function body you will be able to query your write. Otherwise, it’s going to just run through asynchronously and you won’t be able to get your own write back. The times you have seen it, it is likely a result of the speed at which the view udpates.


#3

Thanks for answer.
Actually, this is what I am doing. I totally understand that calls are asynchronous.
In my test I was using async.waterfall model where in first function I doing insert operations, in second - starting indexing process and only after it finished I checking results.


#4

Understood, can you post the code?


#5
var config = require('lib/config');
var couchbase = require('couchbase');
var async = require('async');

var document = 'dev_default';
var viewName = 'test';

var database;

async.waterfall([
    function(callback) {
        database = new couchbase.Connection({
            'host': config.get('database:host'),
            'bucket': config.get('database:bucket')
        }, function(err) {
            if (err) {
                console.log('Can\'t connect to database: %s', err);
                callback(err);
            } else {
                callback(err);
            }
        });
    },
    function(callback) {
        //Removing all old data
        var view = database.view(document, viewName, {stale: 'false'});
        view.query(function(err, data) {
            if(err) {
                console.log('Error during fetching all keys: %s', err);
                callback(err);
            } else {
                var keys = new Array();
                for(var id in data) {
                    keys.push(data[id].key);
                }
                callback(null, keys);
            }
        });
    },
    function(keys, callback) {
        if(keys.length > 0) {
            console.log('Will be removed %s records', keys.length);
            database.removeMulti(keys, {}, function(err) {
                if(err) {
                    console.log('Error during removing keys: %s', err);
                    callback(err);
                } else {
                    callback();
                }
            });
        } else {
            //Nothing to delete
            callback();
        }
    },
    function(callback) {
        var data = {};
        data['key_1'] = {value: {id: 1, name: '1'}};
        data['key_2'] = {value: {id: 2, name: '2'}};
        data['key_3'] = {value: {id: 3, name: '3'}};
        data['key_4'] = {value: {id: 4, name: '4'}};
        data['key_5'] = {value: {id: 5, name: '5'}};
        data['key_6'] = {value: {id: 6, name: '6'}};
        data['key_7'] = {value: {id: 7, name: '7'}};
        database.setMulti(data, {spooled: true}, function(err) {
            if(err) {
                console.log('Error during adding data: %s', err);
                callback(err);
            } else {
                callback();
            }
        });
    },
    function(callback) {
        //Fixing changes
        var view = database.view(document, viewName, {stale: 'false', limit: 1});
        view.query(function(err, data) {
            if(err) {
                console.log('Error during indexing view: %s', err);
                callback(err);
            } else {
                callback();
            }
        });
    },
    function(callback) {
        //Checking results
        var view = database.view(document, viewName);
        view.query(function(err, data) {
            if(err) {
                console.log('Error during getting view: %s', err);
                callback(err);
            } else {
                var result = new Array();
                for(var id in data) {
                    result.push(data[id].value);
                }
                if(result.length != 7) {
                    callback(new Error('Expecting 7, got ' + result.length));
                } else {
                    callback();
                }
            }
        });
    },
    function(callback) {
        //Adding one more record
        database.set('key_8', {id: 8, name: '8'}, function(err) {
            if(err) {
                console.log('Error during adding record: %s', err);
                callback(err);
            } else {
                //Fixing changes, indexing view
                var view = database.view(document, viewName, {stale: 'false', limit: 1});
                view.query(function(err, data) {
                    if(err) {
                        console.log('Error during second indexing view: %s', err);
                        callback(err);
                    } else {
                        callback();
                    }
                });

                callback(err);
            }
        });
    },
    function(callback) {
        //Checking results
        var view = database.view(document, viewName);
        view.query(function(err, data) {
            if(err) {
                console.log('Error during getting view: %s', err);
                callback(err);
            } else {
                var result = new Array();
                for(var id in data) {
                    result.push(data[id].value);
                }
                if(result.length != 8) {
                    callback(new Error('Expecting 8, got ' + result.length));
                } else {
                    callback();
                }
            }
        });
    }
], function(err) {
    if(err) {
        console.log('Test failed: %s', err);
    } else {
        console.log('Test passed');
    }
    process.exit(0);
});

</code>

View code:

<code>
function (doc, meta) {
  if(meta.type == "json" && meta.id.indexOf("key") == 0) {
  	emit(meta.id, meta.id);
  }
}