(Acest articol a fost publicat pentru prima dată pe JottR pe Rși cu amabilitate a contribuit la R-bloggeri). (Puteți raporta problema legată de conținutul acestei pagini aici)
Doriți să vă distribuiți conținutul pe R-bloggeri? dați clic aici dacă aveți un blog, sau aici dacă nu aveți.

The viitor pachetul sărbătorește zece ani pe CRAN începând cu 19 iunie 2025. M-am blocat puțin în timpul sărbătorilor și în timp ce participam la fantasticul utilizator! conferință din 2025, dar, așa cum am promis, iată a patra dintr-o serie de postări pe blog care evidențiază îmbunătățirile recente aduse
viitorverse ecosistem.
TL;DR
În trecut, viitoarele care au fost întrerupte sau întrerupte brusc puneau probabil viitorul ecosistem într-o stare coruptă, în care trebuia să reporniți manual viitorul backend. Acest lucru nu mai este necesar;
-
Futures gestionează acum întreruperile de evaluare
-
Futures gestionează acum concedierile abrupte paralele de lucrători („crashuri”)
-
Lucrătorii prăbușiți sunt reporniți automat
Întreruperi 🛑
Mai jos este un viitor care emulează o expresie R întreruptă la mijlocul evaluării:
library(future)
f <- future({ a <- 42; rlang::interrupt(); 2 * a })
Dacă încercăm să recuperăm valoarea acestui viitor, obținem:
v <- value(f) #> Error: A future () of class SequentialFuture was interrupted #> at 2025-10-15T15:37:09, while running on 'localhost' (pid 530375)
Acest lucru funcționează la fel pentru toate backend-urile viitoare, de ex
plan(future.mirai::mirai_multisession)
f <- future({ a <- 42; rlang::interrupt(); 2 * a })
v <- value(f)
#> Error: A future () of class MiraiMultisessionFuture was
#> interrupted at 2025-10-15T15:39:17, while running on 'localhost' (pid 531734)
Este neobișnuit ca R să se întrerupă astfel, dar se poate întâmpla dacă
plan(sequential) este folosit și utilizatorul apasă Ctrl-C
(comun) sau trimite kill -SIGINT (mai puțin frecvente).
Există și alte modalități de a întrerupe un viitor – mai multe despre asta într-o postare viitoare.
Muncitori prăbușiți 💥
Mai jos este un viitor care emulează un lucrător paralel care încetează brusc („crash”) în timpul evaluării:
library(future)
plan(multisession)
f <- future({ a <- 42; tools::pskill(Sys.getpid()); 2 * a })
Aici tools::pskill(Sys.getpid()) oprește procesul de lucru R care evaluează apelul. În practică, un muncitor se poate prăbuși din diverse motive. De exemplu,
-
Procesul R poate rămâne fără memorie și să fie ucis de sistemul de operare („OOM killer”)
-
Într-un mediu HPC, planificatorul de job ar putea termina lucrătorul dacă depășește limitele de memorie sau de rulare
-
Utilizatorul poate ucide manual lucrătorul (de exemplu,
kill -SIGQUIT) sau anulați lucrarea HPC (
scancelsauqdel)
Indiferent de modul în care lucrătorul paralel este terminat, solicitarea valorii produce:
v <- value(f) #> Error: Future () of class MultisessionFuture interrupted, #> while running on 'localhost' (pid 538181)
Din punct de vedere tehnic, această eroare moștenește și FutureInterruptErrorla fel ca atunci când există o întrerupere a utilizatorului. Acest comportament este consecvent în toate backend-urile, deși unele oferă mesaje de eroare mai detaliate.
Lucrătorii blocați sunt reporniți automat de viitorul backend, ceea ce înseamnă că nu mai trebuie să reporniți manual backend-ul pentru a realiza același lucru.
Rețineți că numai lucrătorul este repornit – viitorul însuși este nu.
Reîncercarea unui viitor întrerupt 🔁
Indiferent de motivul pentru care un viitor a fost întrerupt, îl puteți reporni apelând mai întâi reset()apoi declanșând reevaluarea prin
resolved() sau value().
De exemplu, luați în considerare o funcție problematică care blochează lucrătorul aproximativ 50% din timp:
problematic_fcn <- function(x) {
if (proc.time()(3) %% 1 < 0.5)
tools::pskill(Sys.getpid())
sqrt(x)
}
Dacă chemați un lucrător paralel, am putea reîncerca, să zicem, de până la zece ori, înainte de a renunța:
library(future)
plan(multisession)
f <- future({ problematic_fcn(9) })
for (kk in 10:1)
tryCatch({
v <- value(f)
break
}, FutureInterruptError = function(e) {
if (kk == 1) stop(e)
message("future interrupted, retrying ...")
f <- reset(f)
})
}
message("value: ", v)
Acest lucru ar putea avea ca rezultat:
future interrupted, retrying ... future interrupted, retrying ... future interrupted, retrying ... value: 3
Este un exercițiu distractiv să scrieți o funcție de ajutor future_retry() pentru a simplifica acest lucru ca:
f <- future_retry({ problematic_fcn(9) }, times = 10)
message("value: ", v)
Fie ca viitorul să fie cu tine!
Henrik
