sys.sleep в приложении и parSapply - PullRequest
0 голосов
/ 20 июня 2020

Я использую код, который прерывает выполнение команды на заданное время, чтобы не достичь (crunchbase) API-Limit.

    managed_call <- function(f, events = 44L, every = 60L) {
    force(f)
    minute_ <- rep(NA, events)
    function(...) {       
    m_dif <- as.numeric(Sys.time() - minute_, units = "secs")
    minute_[!is.na(m_dif) & m_dif > every] <<- NA
    calls_remaining <- sum(is.na(minute_))
    if (!calls_remaining) {
    message("Close to API limit, pausing for ", 
    round(every - max(m_dif), 3), " seconds")
    Sys.sleep(every - max(m_dif))
    minute_[which.max(m_dif)] <- NA
    minute_[Position(is.na, minute_)] <<- Sys.time()
    f(...)
    } else {
    minute_[Position(is.na, minute_)] <<- Sys.time()
    f(...)
      }
     }
    }

При применении обычной команды apply или lapply это мир кода дает мне следующее предупреждение:

      Updated <- function(x){is.null(crunchbase_GET(x))}
  
      > abc <- unlist(lapply(websites,Updated))
      Close to API limit, pausing for 1.25 seconds
      Close to API limit, pausing for 1.119 seconds
      ...

Однако я попробовал другой вариант с makeCluster и parSapply:

library("parallel")

abc<- logical(100) 

Updated <- function(x){is.null(crunchbase_GET(x))}
cl <- makeCluster(detectCores(), type = "PSOCK")
clusterExport(cl, varlist = "websites")
clusterEvalQ(cl = cl, library(rcrunchbase))

abc <- parSapply(cl = cl, X = websites, FUN = Updated, USE.NAMES = FALSE)

Предупреждающее сообщение теперь не появляется. Таким образом, мне было интересно, выполняется ли фактическая команда Sys.sleep (), а если нет, есть ли возможность заставить мой код работать с parSapply.

Мне очень жаль, что я не могу дать хороший пример, который может быть воспроизведен для этого конкретного случая c, поскольку user_key требуется для использования rCrunchbase и, таким образом, для получения информации об API Limit et c.

1 Ответ

1 голос
/ 20 июня 2020

message не «сбегает» parSapply, оно теряется, то же самое для cat и warning. Способность передавать базовую c информацию от дочернего cl родительскому процессу затруднительна.

Альтернативой (фактически расширением, поскольку они полагаются на parallel) является future и future.apply, поскольку они имеют дело с выводом на консоль.

cl <- parallel::makeCluster(3)
parallel::parLapply(cl, 1:3, function(i) { message("Hello: ", i+100); Sys.getpid(); })
# [[1]]
# [1] 22680
# [[2]]
# [1] 14504
# [[3]]
# [1] 27084

Но future:

library(future)        # plan, cluster
library(future.apply)  # future_lapply
# using the same 'cl'
plan(cluster, workers = cl)
future_lapply(1:3, function(i) { message("Hello: ", i+100); Sys.getpid(); })
# Hello: 101
# Hello: 102
# Hello: 103
# [[1]]
# [1] 22680
# [[2]]
# [1] 14504
# [[3]]
# [1] 27084

(Вариации могут продемонстрировать, что cat и warning также избегают дочерних процессов.)

...