On 15/05/2021 19:50, Peter Levart wrote:
Another question: Suppose there are two inheritable ScopeLocal
variables with bound values in scope (A and B) when I take a snapshot:
var snapshot = ScopeLocal.snapshot();
now I pass that snapshot to a thread which does the following:
ScopeLocal
.where(C, "value for C")
.run(() -> {
System.out.printf("A:%s B:%s C:%s\n", A.isBound(),
B.isBound(), C.isBound());
ScopeLocal.runWithSnapshot(() -> {
System.out.printf("A:%s B:%s C:%s\n", A.isBound(),
B.isBound(), C.isBound());
}, snapshot);
System.out.printf("A:%s B:%s C:%s\n", A.isBound(),
B.isBound(), C.isBound());
});
What would this code print?
...in other words, does runWithSnapshot replace the whole set of bound
values or does it merge it with existing set?
...let me answer this myself, after checking current implementation. The
answer is: "It depends on whether C is an inheritable ScopeLocal or
non-inheritable". If I understand the code correctly there are two
independent sets of bindings: inheritable and non-inheritable.
snapshot() retrieves the current inheritable set and runWithSnapshot()
replaces current inheriatable set with the snapshot for the execution of
given Runnable and afterwards swaps previous inheritable set back.
So if C is inheritable, the output would be:
A:false B:false C:true
A:true B:true C:false
A:false B:false C:true
...but if C is non-inheritable, the output would be:
A:false B:false C:true
A:true B:true C:true
A:false B:false C:true
This seems consistent. In other words, non-inheritable bindings are
never transferred from thread to thread automatically or by
snapshot/runWithSnapshot. I can see that snapshot/runWithSnapshot was
meant as a mechanism to "simulate" inheritance of bindings when
execution is transferred from one thread to another which is not a newly
started child thread.
Regards, Peter
Peter