I've gotten into the habit of setting a variable to modules which I use over and over to avoid reloading them potentially thousands of times (following some advice in the best practices white paper). I have just noticed that when I build a package the modules don't get pulled in. I would consider this a bug right?
Well, it depends
Logically, it is a bug. But in practice (due to dynamic nature of Javascript) it is hard to detect when a module is being used/referenced, especially when an action call is split on separate variable for module and another expression that does the actual action invocation. So in many cases our code that computes dependency graph to determine which objects should go into package simply cannot detect that a given action is being used, and so the action does not get pulled in.
Well, it depends
Logically, it is a bug. But in practice (due to dynamic nature of Javascript) it is hard to detect when a module is being used/referenced, especially when an action call is split on separate variable for module and another expression that does the actual action invocation. So in many cases our code that computes dependency graph to determine which objects should go into package simply cannot detect that a given action is being used, and so the action does not get pulled in.
I'd be happy if the whole module got pulled in. I can work around it though. Thanks for getting back to me!
Is there a way to set a variable to an instance of an action then execute the action from the var similar to what you can do by specifying a module? I see the object type action has information about the action but I don't see a way of actually executing it.
Yes, there is a way. Let's say you have an action named myaction in module com.vmware.basic, which accepts 2 input arguments of type string and returns a string.
Then the following code should work:
var myfunc = System.getModule("com.vmware.basic").myaction; // get a reference to your action
var result = myfunc("arg1", "arg2"); // execute the action through the reference
What if instead of using code to set the variable I want to make it an attribute of the workflow. I tried this same methodology but it didn't work with an action attribute.
Yes, it won't work directly with action attribute.
Of course, if you really want it, you can use the metadata available in the action attribute (action name, action parameters' names, action's Javascript code) to build a string containing Javascript code to execute a function, and dynamically execute it using eval().
Thanks for all the pointers. I think I can work around it to my satisfaction by setting the attributes within a scriptable task. I guess that task will be analogous to an include statement or require. Hopefully the package system should see everything when I set the values that way.
OK... this is what I ended up with and it seems to meet all my desires. I added an attribute to the workflow for each module so I can have access to all of the actions without having to repeatedly load the module. I also put a dummy call in the scriptable task for each action I intend to use so that it gets pulled into the package when I add the workflow. I tried this and built a package and everything appeared. Do you see anything you would be concerned about in using this method?
// load modules into attribute for use throughout the workflow
var myModuleOne = System.getModule("com.qualcomm.myModuleOne");
var myModuleTwo = System.getModule("com.qualcomm.myModuleTwo");
// faux call to individual actions so they get loaded into the package
if (false) {
System.getModule("com.qualcomm.myModuleOne").action1();
System.getModule("com.qualcomm.myModuleTwo").action2();
System.getModule("com.qualcomm.myModuleTwo").action3();
}