Task termination

I’m trying to get the following to work (or something like it)

function execute(f::Function)
    exec = Executor()

    t = schedule(@task try
            while true
                run!(exec)
                yield()
            end
        catch e
            shutdown!(exec)
            println("done")
            if !isa(e, InterruptException)
                println("Shutdown Executor: $e")
                rethrow(e)
            end
        end
    )

    try
        f(exec)
    finally
        println("shutting down")
        #schedule(@task Base.throwto(t, InterruptException()))
        Base.throwto(t, InterruptException())
        wait(t)
    end
end

But I’m getting strange error I cannot make sense of:
“WARNING: Workqueue inconsistency detected: popfirst!(Workqueue).state != :queued”
or everything hangs.

I get the feeling that maybe the main task not a Task or its acting differently? I’ve read on discourse that you should schedule the throwto, but this also does not work.

What would be a good way to achieve something like this?

1 Like
function execute(f::Function)
    t = schedule(@task try
            while true
                yield()
            end
        catch e
            println("done")
            if !isa(e, InterruptException)
                println("Shutdown Executor: $e")
                rethrow(e)
            end
        end
    )

    try
        f()
    finally
        println("shutting down")
        #schedule(@task Base.throwto(t, InterruptException()))
        Base.throwto(t, InterruptException())
        wait(t)
    end
end

execute(()->println("hello"))

This will give the warning “WARNING: Workqueue inconsistency detected: popfirst!(Workqueue).state != :queued” and then hangs.

I’m guessing that yield does not do what I expect it to do. Changing yield to sleep(0) and using the schedule(@task throwto) method seems to do the what I want, but I cannot explain why it needs to be that complicated. Also I don’t want to sleep…

Thanks in advance

Thanks for the update, I can reproduce this behavior. I also think I found the explanation, although it may not be totally gratifying: https://github.com/JuliaLang/julia/issues/25353#issuecomment-354802975

1 Like

replacing the throwto with

schedule(t, InterruptException(), error=true)

gives

julia> execute(()->println("hello"))
hello
shutting down
done

I use this schedule(...) a fair bit in some of my code and it “mostly works” though sometimes there can be synchronization issues in which case adding a short sleep(...) can help iron out issues (it can be a bit messy but I think there is the project of having a more robust system a la trio in the future, see also this discussion).

2 Likes