Проблем със синхронизация в MongoDB


1
Здравейте, ползвам MongoDB в Node.js приложение и се случва следното: записвам разни неща в базата данни, след това се опитвам да прочета, какво има в базата, но се оказва, че нещата не са записани, след като го пусна още веднъж се оказва, че са се записали след като е преминало търсенето. Тоест трябва да направя така, че да изчакам да се запишат и след това да търся.. Направих си собствена sleep функция: function sleep(delay) { var start = new Date().getTime(); while (new Date().getTime() < start + delay); } И направих така, че една променлива да се променя, чак когато се запише информацията в базата и при влизането в търсенето правя цикъл, в който чакам променливата да се промени и ако не се е променила слийпвам за 100 милисекунди да кажем. Обаче не се получава, цикъла си чака и нищо не се променя. Направих го по този начин, защото нали всичко в node е асинхронно и реших, че онази операция по записването трябва да се изпълни, докато се чака.. Обаче явно нещата не са толкова асинхронни. Някой може ли да ми предложи друг начин за изчакване, който ще работи, или поне да ми обясни, защо това нещо не работи асинхронно. Самия факт, че търсенето се изпълнява преди записването доказва, че нещата работят асинхронно, но в случая не... Малко допълнителна информация: записването в базата се извършва с функция, а търсенето с друга функция и двете функции се пускат една след друга.
Благодаря на всички, който са си изгубили времето тук. {:

в School Academy от Johnny B Goode (0 точки)


Отговори



0
ММм, успях сам да стигна до отговора като помислих малко, ето финалния код:
var sendMessage = function (json) { var unit = new Message({ from: json.from, to: json.to, text: json.text }); sendMessagesTrigger = 42; unit.save(function (err) { if (err) throw err; if(getMessagesTrigger == 42) { getMessagesTrigger = 0; getMessagesForReal(getMessagesJson); } }); }
var getMessages = function (json) { if(sendMessagesTrigger == 42) { getMessagesTrigger = 42; getMessagesJson = json; } else { getMessagesForReal(json); sendMessagesTrigger = 0; } }
var getMessagesForReal = function (json) { Message.find( {$or : [ { $and : [ { from : json.with }, { to : json.and } ] }, { $and : [ { from : json.and }, { to : json.with } ] } ]}) .exec(function (err, units) { if (err) throw err; for (var i = 0; i < units.length; i++) { console.log(units[i]); } }); }
Реално нищо не съм променял в търсенето, магията стана като добавих трета функция и 2-3 следящи променливи. (:
Благодаря на всички, който отговаряха!!!

от Johnny B Goode (0 точки)


2

Доколкото съм запознат с архитектурата на Node.js една таква sleep функция ще блокира света. Node.js не е наистина асинхронен просто изглежда такъв заради концепцията за event loop, при който редиш накакви неща и те се изпълняват някога в бъдещето едно по едно.

Не съм ползвал MongoDB с Node.js но ето какво намерих.

MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
    var collection = db.collection('test_insert');
    collection.insert({a:2}, function(err, docs) { ...

Идеята, че collection.insert ще извика функцията, която си му подал когато е приключил инсърта вместо да седи и да не прави нищо друго докато инсърта не приключи. Ако имаш код, който зависи от това дали нещо е отишло в базата, подай го като callback на insert.

Ако пуснеш още малко код може да го бориме.




0
Ммм, интересно е, разгледах го и си поиграх, но не е това, което ми трябва. Дадох кода в коментар към долния отговор. Не ми върши работа, защото аз реално не винаги извиквам търсенето след като съм записал в базата.. Тоест има си api и например може да извикаш само писането - тогава нямам проблем, може и да извикаш само четенето - тогава също няма нищо, но когато се извикат последователно трябва да се случи такова изчакване и по този начин не мога да се сетя как мога да го постигна..

от Johnny B Goode (0 точки)


2
Ще може ли да добавиш и кода, където записваш нещата в базата. Най-вероятно трябва да преместиш кода, където четеш от базата в някой callback. Пусни кода и ще можем да ти асистираме къде точно е проблемът.

от gallumbits (2371 точки)


0
var sendMessage = function (json) { recorded[i] = 42; i = i + 1; var unit = new Message({ from: json.from, to: json.to, text: json.text }); unit.save(function (err) { if (err) throw err; recorded[i - 1] = 1337; console.log(13); }); }
var getMessages = function (json) { //wait for the messages to be written into db while(i1 <= i) { while(recorded[i1] != 1337) { console.log(recorded[i1]); console.log(i1); sleep(1000); } i1 = i1 + 1; } i = 0; Message.find( {$or : [ { $and : [ { from : json.with }, { to : json.and } ] }, { $and : [ { from : json.and }, { to : json.with } ] } ]}) .exec(function (err, units) { if (err) throw err; for (var i = 0; i < units.length; i++) { console.log(units[i]); } }); }

от Johnny B Goode (0 точки)

0
Ето и кода без изчакването:
var sendMessage = function (json) { var unit = new Message({ from: json.from, to: json.to, text: json.text }); unit.save(function (err) { if (err) throw err; }); }
var getMessages = function (json) { Message.find( {$or : [ { $and : [ { from : json.with }, { to : json.and } ] }, { $and : [ { from : json.and }, { to : json.with } ] } ]}) .exec(function (err, units) { if (err) throw err; for (var i = 0; i < units.length; i++) { console.log(units[i]); } }); }

от Johnny B Goode (0 точки)