ES6 Proxy interceptor with Object Literals self-references

215
December 23, 2017, at 09:46 AM

I have node.JS app that have methods called multiple times with the same parameters. (optimization problem trying out combinations)

The source code is quite large and I'm not familiar with it and I'm trying to find what methods are called multiple times with the same parameters in order to memorize them and improve the performance of the algo.

So I'm trying to intercept all method calls with their respective parameters, store them in Set() and see the difference between the method calls and the unique parameters.

I'm using ES6 Proxy object like so:

process.log = {};
process.traceMethodCalls = function (obj) {
    return new Proxy(obj, {
        get(target, method, receiver) {
            if (typeof process.log[method] === 'undefined') {
                process.log[method] = { calls: 0, params: new Set() };
            }
            return function (...args) {
                process.log[method].calls += 1;
                process.log[method].params.add(JSON.stringify(args));
                return target[method].apply(this, args);
            };
        }
    });
}

Then I can review the log variable for difference in log.calls vs log.params.size() to see the best candidates for memorization.

This technique works great, but obviously does not intercept object literal calls to itself. Here is example where it fails (example module from the project):

module.exports = function (app) {
    const fitness = {
        staticFunction: () => true,
        normalize: (a, b) => {
            return (fitness.staticFunction()) ? a+b : 0;
        }
    };
    return process.traceMethodCalls(fitness); // injected my proxy here
};

After execution I'll have the normalize function in my log variable, but not staticFunction since it wasn't called on the intercepted object but directly on fitness.

What will be the best way to intercept these method calls ?

Answer 1

You could inject your proxy like so:

let fitness = { … };
fitness = process.traceMethodCalls(fitness);
return fitness;

Alternatively, just don't use functions that refer to the original target. Instead, use this:

const fitness = {
    staticFunction() { return true },
    normalize(a, b) {
        return (this.staticFunction()) ? a+b : 0;
    }
};
READ ALSO
Trigger Socket on a Post request

Trigger Socket on a Post request

Trying to emit a message on a POST request, getting an error saying Cannot read property emit of undefined

171
Best way to Post and Retrieve Values using Escape in MySQL

Best way to Post and Retrieve Values using Escape in MySQL

I'm learning to use Node and Express with SQL to handle API calls to my serviceI'm using escape to insert data that users input, but the thing is, it is being inserted with single quotes and when I try to retrieve it, it comes inside single quotes

148
Ejabberd/XMPP Chat Server

Ejabberd/XMPP Chat Server

I am looking to build a chat server using EJABBERD and XMPP but don't know how to startCan anyone share with me good docs/tutorials to follow as a beginner

224