Skip to content

[Question] How to stop a parallel loop when an error has been raised#213

Description

@Jean-Romain

This a question I asked on stackoverflow. Nobody answered so I'm annoying you here 馃槈

I create parallel loops using future. Sometime the expression called raise an error. In that cases the whole process is ran (takes a long time) and the function fails only at the end when the futures are evaluated.

Instead the function should fail when an error is raised. Especially if the error is raised at the beginning of the process. For example this code will fail only after 100 iterations but it is actually likely to fail before the 10th one.

future::plan(future::multiprocess, workers = 4)

g = function()
{  
  x = vector("list", 100)
  for(i in 1:100)  
  {
    x[[i]] = future::future({ h() })
    cat(sprintf("\rProgress: %g%%", i, file = stderr()))
  }  
  return(future::values(x))to
}

h = function()
{
  u = runif(1, 0, 100)
  if (u > 80) 
    stop("Error")
  return(u)
}

How to manage error handling with future? I perfectly understand why it is difficult but in the meantime future_lapply can do it so it is possible.


Btw, I'm actually able to do it but to me it looks more like a kind of hack than a real solution. I'm using a temporary file to communicate the error to the main process.

g = function()
{
  log = tempfile()
  x = vector("list", 100)
  for(i in 1:100)
  {
    x[[i]] = future::future({tryCatch(h(), error = function(e){ write(toString(e), log) })})
  
    if (file.exists(log))  {
      msg = scan(log, character(), quiet = TRUE)
      msg = paste(msg, collapse = " ")
      cat("\n")
      stop(msg, call. = FALSE)
    }
      
    cat(sprintf("\rProgress: %g%%", i, file = stderr()))
  }
  
  return(future::values(x))
}

Thanks

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions