This is a scenario I have and cannot find a clear answer how to avoid observeChanges firing multiple times.
I have this code listening to a player's command, and fire an event to trigger AI to simulate a move:
// Client-side
Deps.autorun(function() {
var query = Games.find({
"playerOne": "PlayerOne",
"playerTwo": "Computer"
});
var handle = query.observeChanges({
changed: function (id, fields) {
// AI makes a move
if (fields.playerTurn == "ComputerTurn" && fields.lastplay)
// lastplay is a timestamp after player has played a turn
Meteor.call("playComputerTurn", id);
}
});
});
//Server-side
Meteor.methods({
'playComputerTurn': function(id) {
// long code to simulate a computer turn
}
});
With a single Meteor process, the event only fires once, but running multiple processes, I don't seem to have an option to let observeChanges ignore the events IF a process has already fired once.
EDIT to be more clear, the events will need to re-run in case of server restarts and during the server heavy calculation player should not be "halted".
Do I need to wrap the Server-side event with a Fiber in queue, or perhaps I have missed something simple here, could someone please help or suggest?
P.S. If simply placing observeChanges in Server-side, the observe will only run once.
There are a number of approaches you could take. You could call the method using the update
callback that changes playerTurn
. Then you wouldn't need an observer at all.
// client
Games.update(gameId, {$set: {playerTurn: "ComputerTurn"}}, function (err) {
if (!err) {
Meteor.call("playComputerTurn", gameId);
}
});
Alternatively, you could do everything in the method that is called when the player takes their turn.
// server
Meteor.methods({
'playComputerTurn': function(gameId) {
var game = Games.findOne(gameId, ...);
// make sure this.id is the current player
// make sure it's this player's turn
// play turn, set playerTurn, lastplay, etc.
// long code to simulate a computer turn
}
});
Also note that if you use an observer, it does not need to run inside of an autorun
unless the selector is reactive.