Closed prodrammer closed 2 years ago
Hello @prodrammer,
the next time I run "ScriptA", it will not import the updated "ScriptB"
Please clarify. By what means – and for what purpose – are you re-running Script A? By all indications, that script is a module, so it produces exports that are accessible directly by anyone who chooses to import them – as many times as necessary and without the need to re-execute Script A's top-level code.
Thank you!
Hi again @prodrammer,
Sorry about the terse response above. To provide a helpful recommendation. we need to understand your scenario.
ClearScript's default document loader does assume that documents in the file system (or on the web) don't change during the application's run, and even if they do, reloading (or re-downloading) is undesirable – not only because it's expensive but also due to the expectation that modules retain identity. Many nontrivial modules have state, and unintended duplication can lead to bugs that are difficult to diagnose.
However, module identity only applies to a given script engine instance. Applications that use multiple instances – and operate in an environment where script documents are subject to frequent change – may indeed favor reloading over the reuse of stale scripts across engine instances. Admittedly, ClearScript doesn't accommodate such applications well at the moment.
Does that describe your application? When you said "the next time I run ScriptA", were you referring to the module being loaded into a new script engine instance?
Thanks!
Edited for clarity and additional detail
In my use case, "ScriptA" is a top-level script. Each time "ScriptA" runs, it's in a new engine instance. When creating the engine, I check if any of the scripts have been updated. If they have, I create a new instance of the DocumentLoader. Otherwise, I reuse the previous instance.
I agree that updating scripts during an engine's lifetime doesn't make sense. That is definitely NOT what I am asking for. Your second scenario "favor reloading over the reuse of stale scripts" is ideal.
Hi @prodrammer,
When creating the engine, I check if any of the scripts have been updated. If they have, I create a new instance of the DocumentLoader. Otherwise, I reuse the previous instance.
Yes, that is indeed a sensible design. To accommodate it, we're currently leaning toward exposing the default loader implementation in a public class – perhaps StandardDocumentLoader
– that the host could instantiate or inherit as necessary.
We'll also do what we can to keep your CreateDocumentLoader
working in the next release and beyond.
Thanks again!
That sounds great. Thanks!
Scenario:
All scripts are run in a single process. I have "ScriptA" which imports "ScriptB" via an
import
statement. If I run "ScriptA", then make changes to "ScriptB", the next time I run "ScriptA", it will not import the updated "ScriptB". After some investigation, I found that the cache in the default DocumentLoader implementation prevents this from happening. I've identified the following potential workarounds:Workaround #1 will not work for my situation, as multiple engines run in the same process and could be in the middle of executing scripts.
Workaround #2 "works" but feels hacky due to questionable thread safety. My gut tells me I'd need to lock access to the cache for the duration of script execution. Long-running scripts and dynamic imports potentially make this worse.
Workaround #3 is a noop. Logic inside the default DocumentLoader implementation forces a minimum cache size of 16.
Workaround #4 is possible using reflection, but hacky at best. The default DocumentLoader implementation is a sealed, nested, private class.
Workaround #5 is also possible, but writing additional code is not ideal, especially when most of the code will be duplicated.
My current choice is workaround #4. It allows me to recreate the document loader after scripts have been updated. Here is the code I had to write to create the new document loader:
As you can see, this is far from ideal and may break in the future if the internal implementation details change.
Suggested fixes:
I'm willing to submit a PR for the above fixes. Please let me know if there are any workarounds I haven't addressed or if you have a better solution.