Get access to the data context of the Meteor.method call inside of a called method

I am trying to lock my site so publications and methods so that from other subdomains they return different data.
As by now I have around 300 Meteor methods, each calling some Model methods that finally make database calls.

Ideally I would use collection hooks and hook insert and find/findOne that they are modifying the query to add a {hostName: this.connection.httpHeaders.host} the problem is inside of the hooks, I have no access to the meteor methods this

is there any way to get the context/this of the publication or method there without passing it all the way through (as the models are shared code)?

Here is one thing you can do:

var _currMethodContext = new Meteor.EnvironmentVariable();
function wrap(fn) {
    return function() {
        var args = _.toArray(arguments);
        var ret;
        _currMethodContext.withValue(this, function() {
            var ret = fn.apply(this, args);
        });
        return ret;
    };
}

what I do with it is:

Meteor.methods({
    "something": wrap(function() {
        this.unblock(); // allow yielding
        var myId = Random.id();
        // while in a given Fiber, _currMethodContext holds the information
        // you set about the "context", which includes connection info
        console.log(myId, _currMethodContext.get().userId, _currMethodContext.get().connection.id);
        // even with many tasks the lead to yielding between Fibers
        // you will not see your context switch 
        console.log(myId, _currMethodContext.get().userId, _currMethodContext.get().connection.id);
    });
})
1 Like

… ok but with hooks and callbacks that might be just “dumped onto the event queue” you might not be running within the same Fiber… I’m not sure about what happens there. @sashko? Anyone?

To add on to the above is one environment variable that does the above. It’s called DDP._CurrentInvocation. So have fun with that. (No extra wrapping, like what I did, actually required.)

Noting that DDP._CurrentInvocation is in “slot 1”… As a further question… And perhaps posing it to @gschmidt with the first commits on dynamics_nodejs.js or @glasser who seems to be “most involved” with its development… What is supposed to be in slot 0… and where can I find it?

Well, the idea behind using Meteor.bindEnvironment (or the other functions that call it for you like wrapAsync) is that it allows you to make sure that your hook or callback is called with the same EnvironmentVariables as the original call. Of course, you have to be sure to consistently use bindEnvironment in functions where you care about this.

I’m not super sure if this helps with the original question; I’m rusty enough on this (have been working on other projects for a while) that I’m not sure how to solve this exactly.

I’m personally a big fan of explicitly passing things down instead of relying on implicitness, though that’s not how a lot of parts of Meteor work by default.

1 Like

So the other miscellaneous question. What is in slot 0?

  • Slot 1 has the DDP._CurrentInvocation, which I prefer to call the “Meteor Method context”
  • Slot 2 has some write fence stuff that I don’t understand yet (will probably look into it eventually)

So what’s supposed to be in slot 0?

Fiber.current leaves it empty.