I'm using Rhino to compile and execute javascript functions. In order to constrain the execution time of scripts, I created a custom ContextFactory where am able to set the max cpu time allowed and the number of instructions before calling observeInstructionCount, similarly to the example described in ContextFactory.
The following code is a sample of the method I use to compile and execute the functions.
CustomFactory factory = new CustomFactory().setMaxCpuTime(300L);
if (!ContextFactory.hasExplicitGlobal()) {
ContextFactory.initGlobal(factory );
}
Context context = factory.enterContext();
Scriptable Scope = context.initStandardObjects();
Function function = context.compileFunction(scope, script, "<func>", 0, null);
(...)
function.call(context, scope, scope, args);
Every thing works as excepted, the scripts that exceed the maximum allowed cpu time throw an Error. My problem is that I want to have two instances of my custom factory under the same JVM, one that will allow the scripts to run for a little longer than the other. But because of the call ContextFactory.initGlobal(factory) every Context will inherit the same ContextFactory. Even if I create a new custom factory with a different allowed cpu time, when I call factory.enterContext() the context will inherit the factory that was passed to initGlobal.
Is there any way to have two instances of ContextFactory (with different properties) under the same JVM?
Related
I see lots of JavaScript references and code snippets on the forum/documentation (like this one) where the execution object is used for a range of useful things, such as:
execution.createIncident(String incidentType, String configuration);
execution.resolveIncident(String incidentId);
execution.setVariable("name", value);
However, nowhere have I seen an example of how to instantiate the execution object, and when I try to use it I get an error like this:
The process could not be started. :
Cannot instantiate process definition Finswitch_Tx:14:42ef803b-67df-11e8-a127-0242ac11001b: Unable to
evaluate script: ReferenceError: "execution" is not defined in <eval> at line number 7
Please could you give me an example of how to instantiate access to that object?
So a more comprehensive answer to this after some help on the Camunda forum.
According to this documentation, all process variables available in the current scope are available to the script by name, as well as some special variables: execution, task and connector.
What's not clear in the documentation is that scripts in the output variables of a connector are running in a child (connector) scope, so while the connector object is available, the execution is not. Some for the functionality on the execution instance can be accessed like this:
var execution = connector.getParentVariableScope();
var activityId = execution.getCurrentActivityId();
However, I see the object returned from is actually an AbstractVariableScope so I'm not sure how far this can be used.
Similarly, inside the script of a Task Listener, the task instance is available, which corresponds to the DelegateTask interface. Here the execution instance can be accessed as follows:
task.execution.getCurrentActivityId();
Within an Execution Listener, the execution instance is accessible directly.
execution.setVariable("testVar", true);
The delegateExecution/delegateTask objects you get from camunda are very complex context hooks that camunda creates based on the current execution state and hands it to the hooks (listener and delegate).
You cannot create that on your own.
If you need to access it, place your code in a Task/ExecutionListener or a delegate, than you have access to it automatically.
GLib's main loop supports scheduling callback functions for periodic intervals, using g_timemout_source_new and related functions. The callback will repeatedly be called after the scheduled interval, until it returns false.
I now want to modify this process with a dynamic interval. Instead of just true or false, the callback should be able to return a time value that should pass until its next invocation.
Doing this in C is quite straightforward: A new GSource Type can be created, that only differs from the timeout source in its dispatch function, which then takes into account the return value when setting the next expiration.
Unfortunately, I am programming an extension for the GNOME Shell, so I'm stuck to JavaScript. The main critical point to porting the above strategy to JavaScript seems to be the equivalent of the g_source_new function, new GLib.Source. First, it requires the length of the struct type to initialize, which would be computed by the sizeof operator in C. I do not know how to get this value in JavaScript. In addition, it is an error to attempt the creation of a GSourceFuncs Struct, the second argument to this constructor, which is needed to hold the dispatch function.
gjs> new imports.gi.GLib.SourceFuncs()
Error: Unable to construct struct type SourceFuncs since it has no default constructor and cannot be allocated directly
How can I create a new GSource in JavaScript?
g_source_new() was not really designed for language bindings and should probably be marked to be skipped when generating bindings for JS or Python.
Including your own private C library, accessed via GObject introspection, as you suggest in your other question, is what I would usually do in an app. However, I have no idea if you can do it for a shell extension.
You should quite easily be able to implement what you want in JS, though. Here's a simple example I wrote from memory that seems like it might do what you want:
const Scheduler = new Lang.Class({
Name: 'Scheduler',
schedule: function (timeMs, callback, priority=GLib.PRIORITY_DEFAULT) {
this._callback = callback;
this._priority = priority;
GLib.timeout_add(priority, timeMs, this._onTimeout.bind(this));
},
_onTimeout: function (
let nextTimeoutMs = this._callback();
this.schedule(nextTimeoutMs, this._callback, this._priority);
return GLib.SOURCE_REMOVE;
},
});
What I would like to do is load javascript to create a library of methods in an object and wait until the object is used for the first time before it is actually defined or compiled. I would like to build references to this object before it is actually fully defined. When I call a method on this object for the first time before the methods on the object are ever defined (meaning the object doesn't actually have methods) I would like to define the object and then call the method. Is there a way to do this using standard syntax such as "MyLibrary.sayHello()" if "sayHello()" is not yet defined on the object.
I imagine it would look like this:
var independentVar = "noCommitments";
var MyLibrary = function(user_ini){
//MyLibrary.init looks like
// (function(ini){
// var a = ini;
// return function(){
// //Notice the method sayHello defines when called,
// // and does not return a reference
// return {
// b:a,c:"c",sayHello:function(z){return "Hello"+a+z}
// }
// }
// })(user_ini);
var d1 = myRequire("MyLibrary.init");
return {
**handleAll : function(){ this = d1(); this.("**calledMethod")}
}
};
var greeting = MyLibrary.sayHello();
alert(greeting);
This is only pseudo-code. If I add a method to cleanup I can then return that object to the uninitialized state of "{**handleAll:function(){/noContext/}}". My application/library has a stub and a link this way and can be used immediately from an undefined state, when building modules this can be useful in order to lower the number of references to a utility, say a post has a menu of functions and those functions are shared by by all posts, -- with a mechanism such as is described here only the "active post"/"post in focus" will reference the utility. It moreless give the ability to activate and de-activate modules. The special part is the modules are already warmed up, they are ready to call functions even though they do not reference them yet, it is similar to live binding but allows the whole user interface to already be defined with functions already stubbed out with the exact name they will have when they are usable. A control mechanism for defaults and debounce is easily found in this model for me.
My question is: Is this type of scripting possible natively or will I have to use some form of compilation like for TypeScript, CoffeeScript or others. I understand it is possible if I pass the method I would like to call as a parameter to a singleton factory. I ultimately would like whole applications that are able to gracefully degrade unused functionality without polluting the code.
What I mean by pollution:
var LibDef = (
function(){
return {
callUndefined:function(methodName){
var returnVal = {}
}
}
})()
var MySingltonLibrary = moduleSinglton.getLibrary("MyLibrary", Lib);
var greeting = MySingltonLibrary.callUndefined("sayHello");
//
// Please use your imagination to consider the complexity in the singlton
The best way that will allow you to tear down an object releasing any space its functions and members consume on the heap and maintain a single reference, that will allow the object to rebuild itself or just rebuild the function that is called is like this - (A very simple model, you may like to use arrays and gradually tear down nested objects internally):
var twentySecondObj(function(window,document){
var base_obj = undefined;
var externalAPI = undefined;
setTimeout(function(){
base_obj = undefined;
},20000);
return function(){
base_obj = (function(base_obj){
if(base_obj === undefined){
return {
property1:"This is property1",
property2:"This is property2"
}
}
})();
externalAPI = (function(){
if(externalAPI === undefined){
return {
property1:base_obj.property1,
property2:base_obj.property2
}
}
})();
return externalAPI;
}
})(window,document);
console.log(twentySecondObj().property1);
On an additional note, you can use getters and setters to observe access to properties and can internally present a facade of both functions and properties which reference a build method like the one above, this way it looks like you are accessing a legit member of the object. There are no options I can think of that will allow you to intercept when attempt to set a new property on an object like: myObj.fooProperty = "foo", and buildup that property into a custom object with a getter and setter, if you have a custom type that needs to be set, then you will have to know it's implimentation details to set it, or call a function passing in the property name and value, or use a method similar to what is shown above.
Here is a link to the proposal for adding weak references to javascript: https://ponyfoo.com/articles/weakref weak-references would alter how this looks, however would not address everything mentioned in this question. Remapping an object when a property is added via some type of deep observer will allow new property members to be enhanced at the time they are set, this would require that the observer ran synchrounously when the property was set, or once the set is complete, the very next statement must be a call to update the object. I will keep posted here for any advances I see that will make the "default handler function" available within javascript in the future.
WeakRef can absolutely be used for recording and handling object usage. I would really like to move object management into webworkers and service workers so they can be maintained through all web endpoints on the domain and do not require to reload across requests. Web frameworks would need to have modified handle to offload all dom changes and updates to worker, essentially a single hook that handles message passing for all hooks. Modload, now must include a message handle name and have task priority meta data so it is properly placed in the least busy or least active worker (slow worker and fast worker) this helps to create an api that can offload to cloud functions, this shpuld give us ability to do more AI, lookups and work offline that is currently handled for most apps in the cloud where more processing power is, and in this way we can gracefully augment local processing with cloud functions only when local resources, or completion times are degraded below acceptable speeds, or above acceptable power policy.
https://v8.dev/features/weak-references
I have one js files . I load it using other javascrupt file using eval() function. I have seen eval is slow and with some other limtation. Since i need to store my JS file object in cache and use it anytime i need after apllication starts. I dont want to do eval() everytime.
Is there anyway to do it in simple way.
var evalObj;
if(evalObj) {
console.log('eval object already evaluated');
_myfunctionInJSFile_(layouts.FormatDate(startTime), threadName, level, categoryName, message);
}
else {
evalObj = eval(fs.readFileSync('./myJSFile', 'utf8'));
console.log('re evaluating object ..' );
_myfunctionInJSFile_(layouts.FormatDate(startTime), threadName, level,message);
}
myJSFile
var _sigmaAlarmHandler_ =function(args)
{
var args = Array.prototype.slice.call(arguments);
args.unshift();
console.log('Alarm : ', args);
}
Either the conditional eval is not working.
In node.js you can simple require your js-file:
var obj = require('./myJSFile');
obj.foo();
./myJSFile.js:
exports.foo = function() {
console.log('foo');
}
This file becomes a module with exported functions, that you need.
It loads once, then every require reuse already loaded module.
If it is not commonjs-compliant (i.e. using module.exports will not work), then you can run it in its own vm:
var vm = require('vm');
vm.runInNewContext(jscode,{/*globalvars*/});
where the second parameter is an object with global vars made available in the context in which the jscode is run. So if the second param is, say, {a:1,b:"foo"} then your jscode will run with the global variable a set to 1 and the global variable b set to "foo".
The jscode itself is a string that you load from a file or elsewhere.
Think of vm.runInNewContext() as "practice safe eval". Well, relatively safe, you can still do some dangerous stuff if you pass in particular vars, like process or file etc.
I used this for the declarative part of cansecurity http://github.com/deitch/cansecurity for nodejs
You can view the sample in the file lib/declarative.js
Here is the API for vm http://nodejs.org/api/vm.html
There are options to run in the same context, etc. But that is very risky.
When you actually run the code, using your example above:
_myfunctionInJSFile_(layouts.FormatDate(startTime), threadName, level,message);
you are looking to pass in 4 params: startTime, threadName, level, message and execute the function. The issue is that you cannot run the function on the current context. You need the function to be defined and run in the file. So you should have something like:
vm.runInNewContext(jscode,{startTime:layouts.FormatDate(startTime),threadName:threadName,level:level,message:message});
And then the jscode should look like
function _myfunctionInJSFile(startTime,threadName,level,message) {
// do whatever you need to do
}
// EXECUTE IT - the above vars are set by the global context provide in vm.runInNewContext
_myfunctionInJSFile(startTime,threadName,level,message);
If you prefer to define the function and have it loaded and run in this context, then just use the commonjs format.
I think i have found the answer for this.
Since my application is running in node js which uses v8 engine platform. When the application starts v8 engine caches all the code/configuration and can be used anytime.
Similarly in my code i will pre-load the JS code using eval and i will do it only once. So on next call i will return only the loaded JS code. Here i need to modify the code to load once.
But main point we have look is that in future if any body has similar requirement they can cache their JS codes using eval (thanks to v8 engine) and use it till your application is running.
If I have several files in a single Apps Script Project that have a function with the same name, how will the scope be determined?
By file?
By dynamic scoping?
By static scoping?
Time of function creation (script file created)?
For example if I have Stuff.gs:
function start() {
var number = getNumber();
}
function getNumber() {
return 5;
}
and More.gs:
function getNumber() {
return 10;
}
And I call start(), how does Google's platform determine which function to call?
I did a test like this, and I didn't get the expected output. The output is 10.0. It seems to me that neither file scope rules are applied, nor static scoping. I created a third file to test further:
Test.gs:
function getNumber() {
return 15;
}
and now the output is 15.0. I further tested and changed 10 to 20 in More.gs to see if the save timestamp determined the scope, but the output was still 15.0.
So to me it seems that the .gs file creation date determines the scope - the most recent timestamp on the file that contains the function name is used. Am I correct in my assumption or is this just a coincidence and it's determined in some other way?
Also, is this specific to Google's Apps Script, or Javascript in general?
Looks like those declarations are all just in global scope. Subsequent definitions will overwrite the previous ones, so if you are first including Stuff.gs, then More.gs, then Test.gs and are calling your function thereafter it would make sense.
The scoping in JS is static (assuming strict mode without with and local eval), but the global scope may be modified dynamically based on the loaded modules (and their order). This is the behaviour in the most JavaScript environments, some also have an additional file (module) scope.