@rlkoshak I’ll reply to this comment here, in an attempt to move the discussion to the forum.
I’ve found the implementation in Core, it’s called ValueCache. I can see that the cache itself is thread-safe (retrieval and storage is protected by locks), but the objects themselves aren’t (they aren’t cloned, and frankly, can’t easily be cloned), so that if one script changes the object, it will potentially change the object in the cache directly, without any concurrency protection. I don’t know the mechanism that sits between the scripting engines and this cache though, I kind of doubt that the Java objects are useful as they are. So, there probably is a conversion along the way, which would “break the link” to the actually cached object, and make it thread-safe because changing it from a script would then only change the converted object. If so, changes wouldn’t be reflected without putting it back to the cache after changing it. The only way this can be “unsafe” is if the object is used directly, as-is.
I’m not familiar with that discussion, but it seems to me like such a cache could be very useful. It’s probably too late to change the existing cache in any drastic way now, but an additional cache could always be added, with different rules. I was thinking about for example serializing everything to JSON in the cache, and let the individual langauge add-on transform the objects to/from something that is useful for that language. It could then become the ObjectCache ![]()
As stated above, I found it. I’d have to see the exact discussion where it was rejected to understand exactly what was rejected, I don’t understand how the ability to share language objects wouldn’t be usefult.
ValueCache is backed by a Map<String, Object>.
I must have missed something then. I could only see one full rule quoted. But, I believe you when new script engines are created for everything.
It just didn’t make any sense to me, why make a ScriptEngineManager if you’re just going to produce new ones? But, given this explanation:
..it starts to make some sense to me. I’m speculating now of course, but what I see could have happened in that originally, ScriptEngineManager did manage script engine instances. But, because of the… “arrangement” with bridging Polyglot Engine and Context through JSR223 where a Polyglot Context becomes a ScriptEngine, this wouldn’t have worked. So, ScriptEngineManager has probably been “tweaked” into producing new engine instances, “because they are cheap in reality as they are just contexts”. “Real” JSR223 implementations will suffer of course, because they actually have to create a whole new engine each time.
Maybe this isn’t how it happened, but at least it’s a model where the pieces can start fitting together in my head.
To me, this seems like a suboptimal design, and I’m questioning if it wouldn’t be better to make something in Core that would allow scripting either through “Polylot” or “JSR223”. But, there might be lots of hurdles in the way, making it difficult.
The details and limitations of this conversion would be of interest to the user of any particular scripting language, and should probably be documented to some extent. It still can’t understand that such conversion doesn’t mean that a new object is created, breaking the link to the “live” cached object. But, the devil might be in the details, maybe GraalVM attempts to do some kind of “live” conversion, where the converted object would reflect changes in the original and vice versa. If so, concurrency would obviously be an issue.
The fact that the timers cause exceptions indicates that they aren’t converted, but are somehow forwarded as Java objects?
I’m not so sure that it means that there’s a reference from the timer to the context, I read somewhere that GraalVM explicitly forbids objects that might cause concurrency issues, so the exception might simply be the result of this: GraalVM deduces that this object can cause concurrency issues, so it isn’t “allowed” - throw exception instead.