Quantcast
Are you the publisher? Claim or contact us about this channel


Embed this content in your HTML

Search

Report adult content:

click to rate:

Account: (login)

More Channels


Showcase


Channel Catalog



Channel Description:

ClearScript is a library that makes it easy to add scripting to your .NET applications. It currently supports JavaScript (via V8 and JScript) and VBScript.

older | 1 | .... | 49 | 50 | (Page 51) | 52 | 53 | .... | 115 | newer

    0 0

    Hi again,

    The JSON object is a JavaScript built-in. If you're using V8, it should be there by default.

    JScript on the other hand implements an older JavaScript standard by default - one that doesn't include JSON. However, it also supports "Standards Mode" in which JSONis implemented. To enable it, pass WindowsScriptEngineFlags.EnableStandardsMode to the JScriptEngine constructor.

    Cheers!

    0 0

    Hello JerryBian!

    Are you using V8? That script engine heavily favors performance over memory efficiency, and is particularly lazy when it comes to garbage collection. If you use a single long-lived V8ScriptEngine instance to run many scripts, you should call ScriptEngine.CollectGarbage() periodically.

    We also recommend that you build ClearScript from the latest source code, as several memory leaks have been fixed since the most recent point release.

    Good luck!

    0 0

    So here's the scenario I'm working with: I have a data coming in from a socket and I'd like to have user provided javascript components processing that data. I have js that conceptually looks like this:
    components.init = function(container) {
      container.register('typeOfData1', myFunction1);
      container.register('typeOfData2', myFunction2);
    }
    
    function myFunction1(args) {
      // do stuff
    }
    
    function myFunction(args) {
      // do more stuff
    }
    Boiled down to essentials my c# code looks something like this:
    public class Container
    {
       ...
       public void register(string dataType, object obj) 
       {
           SaveFunctionObj(dataType, obj);
       } 
       public void Execute(string dataType, string args)
       {
          object obj = GetFunctionObj(dataType);
          dynamic method = obj;
          method(args);
       }
    }
    
    static void Main()
    {
       using (var engine = new V8ScriptEngine())
       {
         var container = new Container();
         dynamic components = new ExpandoObject();
         engine.AddHostObject("components", components);     
    
         // get scripts that look like the js above
         foreach(string script in GetTheScripts())
         {
           engine.Evaluate(script);
           components.init(container);
         }
    
         // start a long-running loop
         while (true) 
         {
           var data = GetData();
           container.Execute(data.DataType, data.Args);
         } 
      }
    }
    Sorry for all the code, just wanted to be clear in how I was approaching the problem. I basically have a bunch of scripts which respond to certain data coming in. I have some C# code that holds references to functions that exist in the scripts and runs each as needed.

    I built this prototype and to my amazement the whole thing just worked, right off the bat. So, amazing job ClearScript team. Really incredible framework you've written.

    I am a complete ClearScript newb, so my questions are:
    1. Is this a good idea? Should I be holding on to references to functions that exist in the script the way I am? Are there bad performance implications of doing so?
    2. Does it make sense to have one engine for all scripts? From what I've been reading it's expensive to create multiple engines. I may have 20-30 different scripts, so it sounds like I don't want 30 different engines running.
    3. I'd love to listen for file changes and automatically update the running engine using the method above. I can do book keeping and get rid of my C# references to the js functions for that file. However the engine would still hold those references wouldn't it? Would the engine know to clean those up?

    0 0

    Greetings!

    Thank you for the positive feedback!

    Is this a good idea? Should I be holding on to references to functions that exist in the script the way I am? Are there bad performance implications of doing so?

    Easy access to script objects and functions is one of ClearScript's fundamental goals. That said, accessing a script object or invoking a script function is relatively expensive. It involves the use of .NET's dynamic infrastructure, managed-to-native transitions, argument marshaling, lock acquisition, etc.

    Does it make sense to have one engine for all scripts? From what I've been reading it's expensive to create multiple engines. I may have 20-30 different scripts, so it sounds like I don't want 30 different engines running.

    It really depends on your application's requirements. If you need concurrent script execution, you need multiple engines. If you need to run each script in a pristine environment, you can use one V8 runtime to efficiently spawn a separate engine for each script, or just create and dispose engines as necessary. There are definitely tradeoffs, but even for server applications that require maximum concurrency, we recommend using a small pool of engines or runtimes. As with worker threads, the sweet spot is somewhere in the neighborhood of your CPU core count.

    I'd love to listen for file changes and automatically update the running engine using the method above. I can do book keeping and get rid of my C# references to the js functions for that file. However the engine would still hold those references wouldn't it? Would the engine know to clean those up?

    The CLR and the script engine have independent object systems and garbage collectors, and proxies are used on each side to refer to objects on the other. A proxy by necessity prevents its target from being collected. When the proxy itself is collected, its target is released to its garbage collector only if no other reachable references exist on either side.

    In your case, the script leaves global references to myFunction1() and myFunction2(), so they can't be collected even after the managed references are gone. It would be different if your script looked like this:
    components.init = function (container) {
        container.register('typeOfData1', function (args) { /* do stuff */ });
        container.register('typeOfData2', function (args) { /* do stuff */ });
    }
    Another consideration is that V8's garbage collector is extremely lazy. If your application uses long-lived V8ScriptEngine or V8Runtime instances, we strongly recommend that you periodically call CollectGarbage().

    Thanks again, and good luck!

    0 0

    Hi ClearScript,

    Thanks for your answer, I have a quick question: should I create a new instance of VBScriptEngine each time or use a single instance globally?

    0 0

    Hi again,

    Regarding your first question, there are several considerations. Do you need to run scripts concurrently? Are your scripts independent, or do they reuse data left over by other scripts? Are your scripts trusted and known to be well-behaved? What are your performance requirements? It's difficult to say what you should do without knowing more about your application.

    As for memory leaks, we aren't aware of any in the latest ClearScript code, but there may always be bugs in ClearScript and/or the underlying script engines. Can you provide more information? Which script engine(s) are you using? What do your scripts do, roughly speaking? Does your leak detection tool provide any clues? Can you post a minimal code sample that demonstrates the issue?

    Thanks!

    0 0

    That's just what I needed to know. I'll give it a try using the runtime to spawn the needed engines as I indeed need concurrent execution and it would ensure a pristine script environment. Thanks so much for addressing all of my questions!

    0 0

    No problem at all!

    Just to clarify, each V8 runtime supports single-threaded access only, but multiple runtimes can operate concurrently. In ClearScript, the V8ScriptEngine constructor creates a private runtime for each instance, but you can also create a runtime explicitly, and then call V8Runtime.CreateScriptEngine() to create one or more engines that share that runtime. Engines that share a runtime cannot be used concurrently.

    Cheers!

    0 0

    Just to make sure I understand correctly:

    If I were to use one V8Runtime to efficiently spawn the needed engines, in my scenario each engine would only be tied to one script and the script would be evaluated only once. Then on the C# side I'd call something similar to the code above: container.Execute(data.DataType, data.Args) concurrently. So in the end, the functions which are contained in the script and hence each engine, would be accessed concurrently. And that is not supported because of the shared runtime, right?

    If I have that right and opt to not share a runtime are there performance implications?

    0 0

    Hi again,

    So in the end, the functions which are contained in the script and hence each engine, would be accessed concurrently. And that is not supported because of the shared runtime, right?

    That's correct. If the engines share a runtime, the scripts will be executed sequentially.

    If I have that right and opt to not share a runtime are there performance implications?

    Yes. Two engines with private runtimes are heavier than two engines that share a runtime, mostly in terms of memory usage. V8 runtimes also reserve large blocks of address space, and while that's not as expensive as actual allocation, a few dozen runtimes can easily exhaust the address space of a 32-bit process.

    This is why we recommend that servers and other multithreaded applications use small runtime pools. Another possibility is simply to create and dispose runtimes on demand, effectively letting the thread pool be the master resource manager, but because runtimes have startup and teardown costs, this approach will not perform as well.

    Good luck!

    0 0

    Hi ClearScripts,

    I would like to raise an excpetion within the JavaScript code. For sure I may raise the Error object but I need to have something more specific. I didn't find out how to raise an .NET exception. Is there any way to do this?

    Best regards,
    Torsten

    0 0

    Hello, Torsten!

    You can easily expose a function that throws a host exception. For example:
    engine.Script.throwBadArg = new Action<string, string>((message, paramName) =>
    {
        thrownew ArgumentException(message, paramName);
    });
    Keep in mind that exceptions thrown in this manner are likely to be wrapped by ScriptEngineException by the time they reach the host, so you'll have to use InnerException or GetBaseException() to examine them.

    On the other hand, if you need to catch and examine exceptions in JavaScript code, we recommend that you use JavaScript exceptions. Being normal JavaScript objects, they offer nearly infinite flexibility. That said, it is possible to catch and examine host exceptions in script code. See this thread for more information.

    Good luck!

    0 0

    Thanks for your answer!

    As I see, I cannot
    • identify in the host application a JavaScript defined exception, like
    function myException(message, 
    {
    this.name = 'myException';
    this.message = message + ' ' + id;
    this.id = id;
    };
                              
    myException.prototype = new Error();
    myException.constructor = myException;
                                
    throw new myException('this is a message', 42);
    I only get the ScriptEngineException with the message as text. And
    • identify within my JavaScript code the type of the CLR exception, like
    try {
       throwBadArg('one', 'two');
    } 
    catch (ex)
    {
       if (ex instanceof ArgumentException)
       {
          // ...
       }
       else
       {
          // ...
       }
    }
    (I added the type to the engine before executing code).

    Is that right? I only want to be sure that I haven't overlooked something.

    Best regards,
    Torsten

    0 0

    I hava a question.

    We can load other javascripts from javascript with load("xxx.js") with Rhino.

    Can we load other javascripts from javascript with ClearScript?

    Could you tell me how we can do for this if we can.

    0 0

    That's correct.

    ClearScript doesn't expose managed exceptions directly to script-based handlers. The best approach is to catch managed exceptions in managed code and pass them to script code for analysis. This thread includes sample code for doing so.

    Similarly, it's best to catch script exceptions in script code and pass them to the host if necessary. You can find an example here.

    Cheers!

    0 0

    Hello!

    You can easily expose a Rhino-like load() function:
    publicdelegatevoid LoadFunc(paramsstring[] paths);
    // ...
    engine.Script.load = new LoadFunc(paths => {
        foreach (var path in paths) {
            engine.Execute(File.ReadAllText(path));
        }
    });
    Good luck!

    0 0

    Hi ClearScript,

    I would try to provide as more information as possible.

    Users can execute some custom scripts targets to our system, in our server side, we plan to use ClearScript(V8ScriptEngine) to parse and execute the input scripts. All the scripts are independent, they can be run concurrently, so no reused data left over by others.

    Speaking of memory leaks, we have some simple codes to demonstrate it.
    public class TestData
    {
        private readonly string _bigData;
    
        public TestData()
        {
            _bigData = new string('*', 1024 * 1024);
        }
    
        public Guid Id { get; set; }
    
        public DateTime Created { get; set; }
    }
    
    public class CloudService
    {
        public double Calculate(double num1, double num2)
        {
            return num1 + num2;
        }
    
        public TestData CreateObj()
        {
            return new TestData
            {
                Created = DateTime.Now,
                Id = Guid.NewGuid()
            };
        }
    
        public void Output(object obj)
        {
            EngineContext.Output.WriteLine(obj);
        }
    }
    And we exposed CloudService like this:
    ScriptEngine.AddHostObject("service", new CloudService());
    Here is how we execute the scripts:
    public void RunScript()
    {
        const int loopNumber = 100;
        double totalTime = 0;
        var output = string.Empty;
        for (var i = 0; i < loopNumber; i++)
        {
            try
            {
                var stopwatch = Stopwatch.StartNew();
                ScriptEngine.Execute(Scripts);
                stopwatch.Stop();
                totalTime += stopwatch.Elapsed.TotalMilliseconds;
                output = EngineContext.Output.ToString();
            }
            catch (Exception ex)
            {
                output = ex.ToString();
            }
    
            EngineContext.Output.GetStringBuilder().Clear();
        }
    
        Output = string.Format("{0}{1}{4} {1}Execution Performance:{1}\rTotal: {2} ms{1}\rAverage: {3} ms.", output,
            Environment.NewLine, totalTime, totalTime / loopNumber,"=========================");
    }
    We executed the input scripts 100 times to evaluate the performance. The ScriptEngine is global instance, which means we reused it for every script execution.

    And the test script:
    var obj = service.CreateObj();
    service.Output(obj.Id);
    We found the memory increased 200MB after the execution, and mostly are HostItem instance(200+ count), all of them has TestData instance with 1MB big data field. Besides that, we fired a timer which call ScriptEngine.CollectGarbage(true) every 1 second, it doesn't help too much.

    We use dotMemory to detect the memory issue, here are two screenshots:
    Memory Clue
    HostItem

    Here is our question

    1. Did we use ClearScript in wrong way? You can check the full code here. Use global ScriptEngine instance or create one each time in our scenario?
    2. Can you introduce the cache mechanism succinctly? For example, if all the input scripts are same, ClearScript will cache the only one copy in memory to increase performance or cache every scripts? Do we need to cache it by ourselves?
    3. What's the next release plan, we don't want to compile source code by ourselves?

    0 0

    Hello,

    I was trying to build on Windows 7 x64, but was having issues. After a bit of debugging I've "solved" the issue for me. I'm just posting to make you aware if you aren't already.

    It's a simple bug within V8Update.cmd

    Basically, you're assuming that I am using VS 2012, when I'm using VS2010.

    The part in question is here:
    :SetMSVSVersion
    if "%VisualStudioVersion%"=="12.0" goto UseMSVS2013
    set GYP_MSVS_VERSION=2012
    goto SetMSVSVersionDone
    :UseMSVS2013
    set GYP_MSVS_VERSION=2013
    :SetMSVSVersionDone
    After changing set GYP_MSVS_VERSION=2012 to set GYP_MSVS_VERSION=2010 it started working for me.

    0 0

    I am looking to toy with javascript proxies how can I set v8 to enable experimental javascript?

    0 0

    Greetings!

    As you've discovered, a full ClearScript build requires Visual Studio 2012 or 2013. A "NoV8" or custom build may be possible with an earlier Visual Studio version, but we don't test with those and cannot guarantee future compatibility.

    By the way, Visual Studio Express 2013 for Windows Desktop is available at no cost.

    Cheers!

older | 1 | .... | 49 | 50 | (Page 51) | 52 | 53 | .... | 115 | newer