Skip to content

Stale data is received if doing a findOne after an update #13

@wildhart

Description

@wildhart

If quickly doing a findOne(field) after an update() then stale data is received. Contrived example:

const name = Meteor.user('profile').profile.name;
console.log('before', name);  // -> "bob"
Meteor.users.update(Meteor.userId(), {$set: {"profile.name": name+name.length}});
console.log('after ', Meteor.user('profile').profile.name); // -> "bob"  - should be "bob3"

This is a contrived example for demonstration purposes, but I have hit this bug in real production code.

My work-around involves a bit of a hack of Meteor.EnvironmentVariable to set an environment variable within the Fiber whenever the Meteor.users collection is updated:

const _origUpdate = Meteor.users.update;
const updated = new Meteor.EnvironmentVariable();
var Fiber = Npm.require('fibers');

// https://github.com/meteor/meteor/blob/096641b084b70f4ab52f3ef4468728d164ec66d1/packages/meteor/dynamics_nodejs.js#L47
Meteor.EnvironmentVariable.prototype.set = function(value) {
	Meteor._nodeCodeMustBeInFiber();
	if (!Fiber.current._meteor_dynamics) Fiber.current._meteor_dynamics = [];
	var currentValues = Fiber.current._meteor_dynamics;
	currentValues[this.slot] = value;
}

// Set an environment variable whenever the Meteor.users collection is updated
Meteor.users.update = function(...args) {
	updated.set(true);
	return _origUpdate.apply(this, args);
}

Meteor.user = function (input) {
	// don't hit the cache if the Meteor.users collection has been updated in this Fiber
	if (typeof input === "undefined" || updated.get()) {
		return _original();
	}
	...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions