Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signal interrupts are not propagated to worker nodes in background sessions with parallel clusters #294

Open
mihaiconstantin opened this issue Nov 20, 2024 · 0 comments

Comments

@mihaiconstantin
Copy link
Contributor

mihaiconstantin commented Nov 20, 2024

Suppose you have the following background session object with a parallel cluster object.

# Create a new `R` background session.
session <- callr::r_session$new()

# Create a cluster with two worker processes and record the process IDs.
worker_pids <- session$run(function() {
    # Create a cluster.
    cluster <<- parallel::makeCluster(spec = 2, type = "PSOCK")

    # Return the worker process IDs.
    return(unlist(parallel::clusterCall(cluster, Sys.getpid)))
})

# Run a task in the background that keeps the cluster busy indefinitely.
session$call(function() {
    # Send the task to the cluster workers.
    parallel::parSapply(cluster, 1:10, function(x) {
        # An infinite loop.
        while (TRUE) { Sys.sleep(0.0001) }
    })
})

# Interrupt the session.
session$interrupt()

# Read the session interruption condition.
session$read()

# Confirm the session is `idle`.
session$get_state()

The following will hang indefinitely on macOS because the workers are still busy (i.e., I believe the SIGINT signal is not propagated to the workers). However, it will output as expected on Windows.

# Send the run and output the results.
session$run(function() {
    parallel::clusterCall(cluster, print, "Subsequent cluster call.")
})

At this point I sent a manual interrupt (i.e., Ctrl + C) on macOS.

# Close the session.
session$close()

# Remove the reference to the `session` object.
rm(session)

# Request garbage collection.
gc(full = TRUE)

On macOS the worker processes are still running.

# Check the status of the worker processes.
lapply(worker_pids, function(pid) {
    ps::ps_is_running(
        ps::ps_handle(pid)
    )
})

# Clean.
tools::pskill(worker_pids, tools::SIGTERM)

Is this expected behavior? Am I missing something obvious?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant