Hacker News new | ask | show | jobs
by zamber 2145 days ago
The only viable way to avoid an endless while loop or overly heavy operations is to have a worker do the eval(), though it would defeat the meta-programming aspect and isolate execution making it pretty much useless. It's still possible to proxy local objects via comlink (or implement your own worker proxy) but it would limit communication to POJO's so no dynamic module imports and access to non-serializable objects.
1 comments

Right, where you could send the worker a terminate signal if some conditions were met like time or no response or too many responses...

And that drawback obsoletes the strategy it seems, unfortunately.

It's an interesting problem, how to provide full access and control as well as non-corruptible recovery systems.

One of the biggest problems I consistently run into is that printing to the screen is a slow operation, every learns this day one of any graphics work, but things like console.log or Node.appendChild are the primary way to destroy someone's computer for a short period of time because orders of magnitude more operations are queued up before they can complete. I wonder if painting operations could be limited to some max number per second to prevent that orders of magnitude queue problem. And, more importantly, how do you code that limit?

> One of the biggest problems I consistently run into is that printing to the screen is a slow operation, every learns this day one of any graphics work, but things like console.log or Node.appendChild are the primary way to destroy someone's computer for a short period of time because orders of magnitude more operations are queued up before they can complete. I wonder if painting operations could be limited to some max number per second to prevent that orders of magnitude queue problem. And, more importantly, how do you code that limit?

For node.appendChild you have the whole virtual DOM thing leveraged by modern JS frameworks. If you hit issues try using any framework that boasts having a virtual DOM.

The same strategy could be done for the console to some extent.

The built-in console object is over-writable so you can add a layer that would batch console calls (if you do many in a short time). Note that this will break the call address you have on the right-hand side. Also IE11 does strange things with the console object depending if devtools are open or not.

The solution above is doable but it's a hack. If you really have to call console a lot of times in a short time adding a custom log method would be better.

    globalThis.__debugLog = [];
    globalThis.__printLog = () => globalThis.__debugLog.forEach(i => console.log(i));

    const log = (...args) => globalThis.__debugLog.push(args);
 
    // then in code:
    log(whatever);

    // and once you want to check it, call printLog in the console
    __printLog();
Again with this solution you don't know where the call happens but it's a starting point. I recently started using the pattern above to debug performance and memoization issues I had in heavily used code. The console wasn't readable anymore without it. Console.table is helpful for printing out bigger sets of debug data btw.

For canvas setTimeout on requestAnimationFrame seems to do the trick https://stackoverflow.com/questions/19516307/limiting-framer... I don't to much with canvas besides using it indirectly with libraries.

I meant to dig more into requestAnimationFrame, thanks for the prompt. I should clarify, the problem is that you can crash a web page if you do any animation inside of a runaway loop but especially painting with console. I suppose this indirection might help you realize that before it happens though, and that's probably worth doing. Thanks for the code.
You're welcome. I avoid runaway loops like fire because the crashes tend to be problematic to debug. Consider the timeout thing from SO. Generally working with events in JS is easier than central run loops.
> Generally working with events in JS is easier than central run loops.

That's an interesting perspective I hadn't thought of before, I'll see if that can inspire some design pattern. Thanks for another good prompt!

You may want to read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Even...

Note that it does not mention promises and async/await but it does include it. Promises are essentially syntactic sugar for a setTimeout calling success and failure methods. This also means that promise code will be executed in parallel but on one thread and one heap, so each promise will fight with all other for priority. This is generally fine for async stuff like fetching resources but it would completely destroy performance if it would do anything heavy, like, say unzipping zips with jszip.

Historically the event-driven model of JS enabled Node.js's API to be callback-driven. This lead to what is called "callback hell" and eventually to a proper introduction of promises and async/await to the language.