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

Reply via email to