[SERVER-24089] Add method to allow JS functions to take in parameters when converted to a string. Created: 06/May/16  Updated: 06/Dec/22  Resolved: 03/Dec/21

Status: Closed
Project: Core Server
Component/s: JavaScript, Testing Infrastructure
Affects Version/s: 3.3.5
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Robert Guo (Inactive) Assignee: Backlog - Server Tooling and Methods (STM) (Inactive)
Resolution: Won't Fix Votes: 1
Labels: stm, tig-mongorunner
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Assigned Teams:
Server Tooling & Methods
Participants:

 Description   

When passing code to parallel shells through StartMongoProgramNoConnect or StartParallelShell, the easiest way to know about variables in the caller's scope is to construct the code from a string. e.g. startParallelShell(coll + '.find()')

This is unwieldy for any code longer than a one liner. We should consider adding a method to the Function object, something along the lines of toStringWithArgs(argsObj), that will construct the variables for you. e.g.

var f = function(coll) {return coll.find()}
var s = f.toStringWithArgs({coll:coll})
// s will be "var coll = 'test.test'; var f = function(coll) {return coll.find()}"
startParallelShell(s)

This solution is not perfect. Ideally we'd want to replace things the variables when Function.toString() is called, but it doesn't look like that is possible in JS at the moment.



 Comments   
Comment by Brooke Miller [ 03/Dec/21 ]

STM doesn't have bandwidth to pick this up, so we're closing as won't fix. However, if other teams have capacity and would like to pursue this, please feel free to pick this up.

Comment by Max Hirschhorn [ 07/May/16 ]

I've thought about this before and was hoping that template strings would give a nice way forward. However, I'm not sure there's a way to make use of template strings while still defining a function expression so that useful linting occurs. Instead, I've been thinking along the lines of having users defining a function that takes parameters and returning a string that represents calling that function with the state of the parameters passed in.

function functionToStringWithArgs(func, ...args) {
    args = args.map(arg => tojson(arg));
 
    if (args.length !== func.length) {
        throw new Error('function expects ' + func.length + ' arguments, but found ' + args.length);
    }
 
    return "function() { (" + func.toString() + ")(" + args.toString() + "); }";
}

Instead of writing it as function(coll) {return coll.find()}, you could write it as something like

functionToStringWithArgs(function(dbName, collName) {
    var coll = db.getSiblingDB(dbName)[collName];
    coll.find();
}, coll.getDB().getName(), coll.getName());

However this still has the issue where if this function expression is defined within a context where coll is also defined, then omitting the coll declaration within the function wouldn't be an error from the linter's perspective, but only an error upon evaluating the function. On the upside, we'd get formatting and some linting with a way to pass additional data into startParallelShell()'d functions.

Generated at Thu Feb 08 04:05:21 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.