Versions Compared

Key

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

...

Code Block
languagejava
     try (var scope = FiberScope.cancellableopen()) {
         var fiber1 = scope.schedule(task);
         var fiber2 = scope.schedule(task);
     }

A thread or fiber creates and enters a scope by calling the FiberScope.cancellable method (we will explain cancellation later)open method. It exits the scope when the code in the block completes and any fibers scheduled in the scope have terminated. The example schedules two fibers. The thread/fiber executing the above code may have to wait (in the FiberScope’s close method) until the two fibers have terminated.

...

Code Block
languagejava
        try (var scope1 = FiberScope.cancellableopen()) {
            scope1.schedule(task);
            try (var scope2 = FiberScope.cancellableopen()) {
                scope2.schedule(task);
            }
            scope1.schedule(task);
        }

...

Code Block
languagejava
    void x() {
        try (var scope1 = FiberScope.cancellableopen()) {
            var fiber1 = scope1.schedule(() -> foo());
            var fiber2 = scope1.schedule(() -> bar());
        }
    }
    void foo() {
        try (var scope2 = FiberScope.cancellableopen()) {
            scope2.schedule(() -> task());
            scope2.schedule(() -> task());
        }
    }
    void bar() {
        try (var scope3 = FiberScope.cancellable()) {
            scope3.schedule(() -> task());
            scope3.schedule(() -> task());
        }
    }    

...

As an escape hatch, the FiberScope API defines the detachedstatic background() method to return a the background scope which can be used to schedule fibers that are intended to outline the context where they are initially scheduled.

...

Decomposing deadline or timeouts is very difficult to get right. 

FiberScope supports creating and entering a scope with a deadline, expressed as a java.time.Instant. If the deadline expires is reached before the thread/fiber exits the scope then all fibers scheduled in the scope are cancelled and the close method throws an exception (or it gets added as a suppressed exception when exiting with an exception).

Deadlines work with nested scopes. Consider the following:

Code Block
languagejava
        var deadline = Instant.now().plusSeconds(10);
        try (var scope1 = FiberScope.withDeadlineopen(deadline)) {
            try (var scope2 = FiberScope.cancellableopen()) {
                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 is reached 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.

In addition to withDeadline, FiberScope also defines withTimeout to open(Duration timeout) to enter a scope with a timeout, expressed as a java.time.Duration. If the timeout expires before thread/fiber exits the scope then all fibers scheduled in the scope are cancelled.

...

    Nathaniel J. Smith: Timeouts and cancellation for humans

...

Fibers communicate to other fibers or threads using queues or other mechanisms. They may also return a result, retrieved by invoking the Fiber’s join method. As a convenience when scheduling fibers in a

FiberScope

...

Code Block
languagejava
try (var scope = FiberScope.cancellable()) {
    var queue = new FiberScope.TerminationQueue<String>();

    Arrays.stream(tasks).forEach(task -> scope.schedule(task, queue));

    IntStream.range(0, tasks.length)
            .mapToObj(x -> queue.takeUninterruptibly())
            .map(Fiber::join)
            .forEach(System.out::println);
}

FiberScope Variables/Locals

There is no support yet at this time for making context available to all fibers scheduled in the scope. InheritedThreadLocals can be used in the mean-time.

...