Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

FiberScopes can be nested, consider the following:

...

Code Block
languagejava
        try (var scope1 = FiberScope.cancellable()) {

...


            scope1.schedule(task);

...


            try (var scope2 = FiberScope.cancellable()) {

...


                scope2.schedule(task);

...

            }

...


            }
            scope1.schedule(task);

...


        }

In this example, a thread or fiber enters scope1, schedules a fiber, then enters scope2 where it schedules a fiber in that scope. The execution cannot exit scope2 until the fiber scheduled in that scope terminates. When it exits, it is back in scope1. It cannot exit scope1 until the two fibers scheduled in that scope have terminated.

Structured concurrency leads naturally to trees of tasks. Consider the following method x that schedules two fibers to execute foo and bar. The code in foo and bar each schedule two fibers.

...

Code Block
languagejava
    void x() {

...


        try (var scope1 = FiberScope.cancellable()) {

...


            var fiber1 = scope1.schedule(() -> foo());

...


            var fiber2 = scope1.schedule(() -> bar());

...

        }
    }

...


        }
    }
    void foo() {

...


        try (var scope2 = FiberScope.cancellable()) {

...


            scope2.schedule(() -> task());

...


            scope2.schedule(() -> task());

...

        }
    }

...


        }
    }
    void bar() {

...


        try (var scope3 = FiberScope.cancellable()) {

...


            scope3.schedule(() -> task());

...


            scope3.schedule(() -> task());

...

        }

        }
    }    

...

fiber1 is scheduled in scope1. It enters scope2 and schedules two fibers. It exits scope2 (and returns to scope1) when the two fibers terminate. fiber2 is scheduled in scope1. It enters scope3 and schedules two fibers. It exits scope3 (and returns to scope1) when the two fibers terminate. The thread or fiber executing will not exit scope1 until fiber1 and fiber2 have terminated.

...

Deadlines work with nested scopes. Consider the following:

...

Code Block
languagejava
        var deadline = Instant.now().plusSeconds(10);

...


        try (var scope1 = FiberScope.withDeadline(deadline)) {

...


            try (var scope2 = FiberScope.cancellable()) {

...


                scope2.schedule(() -> task());

...

            }   

...


            }   
        }

scope1 is entered with a deadline that is now + 10s. It schedules a fiber in scope2 and cannot exit to scope1 until the fiber terminates. If the deadline expires in the meantime then the fiber will be cancelled and the thread/fiber will throw CancelledException(“Deadline expired”) when existing scope1. If the inner scope had a deadline that was further into the future that the deadline then the deadline for the outer scope will expire first.

...