Для одного из моих модулей сбора данных диссертации я реализовал простой механизм опроса. Это необходимо, потому что я делаю каждый запрос на сбор данных (один из многих) в виде SQL-запроса, представленный через веб-форму, который имитируется кодом RCurl. Сервер обрабатывает каждый запрос и генерирует текстовый файл с результатами по определенному URL-адресу (RESULTS_URL
в коде ниже). Независимо от запроса, URL и имя файла совпадают (я не могу это изменить). Поскольку время обработки для разных запросов данных, разумеется, различно, и некоторые запросы могут занимать значительное количество времени, мой код R
должен "знать", когда результаты готовы (файл сгенерирован), чтобы он мог извлеките их. Следующее - мое решение для этой проблемы.
POLL_TIME <- 5 # polling timeout in seconds
В функции srdaRequestData()
перед выполнением запроса данных:
# check and save 'last modified' date and time of the results file
# before submitting data request, to compare with the same after one
# for simple polling of results file in srdaGetData() function
beforeDate <- url.exists(RESULTS_URL, .header=TRUE)["Last-Modified"]
beforeDate <<- strptime(beforeDate, "%a, %d %b %Y %X", tz="GMT")
<making data request is here>
В функции srdaGetData()
, вызываемой после srdaRequestData()
# simple polling of the results file
repeat {
if (DEBUG) message("Waiting for results ...", appendLF = FALSE)
afterDate <- url.exists(RESULTS_URL, .header=TRUE)["Last-Modified"]
afterDate <- strptime(afterDate, "%a, %d %b %Y %X", tz="GMT")
delta <- difftime(afterDate, beforeDate, units = "secs")
if (as.numeric(delta) != 0) { # file modified, results are ready
if (DEBUG) message(" Ready!")
break
}
else { # no results yet, wait the timeout and check again
if (DEBUG) message(".", appendLF = FALSE)
Sys.sleep(POLL_TIME)
}
}
<retrieving request results is here>
Основной поток/последовательность событий модуля является линейным, следующим образом:
Read/update configuration file
Authenticate with the system
Loop through data requests, specified in configuration file (via lapply()),
where for each request perform the following:
{
...
Make request: srdaRequestData()
...
Retrieve results: srdaGetData()
...
}
Проблема с приведенным выше кодом заключается в том, что она не работает , как ожидалось: при выполнении запроса данных код должен печатать "Ожидание результатов"...", а затем, периодически проверяя файл результатов для изменения (сгенерированный), печатайте точки выполнения до тех пор, пока результаты не будут готовы, когда он распечатает подтверждение. Однако фактическое поведение заключается в том, что код ждет много времени (я намеренно сделал один запрос долговременным), а не печатал что-либо, но затем, по-видимому, извлекает результаты и печатает как "Ожидание результатов".. "и "Готов" в то же время.
Мне кажется, что это какая-то проблема синхронизации, но я не могу понять, что именно. Или, может быть, это что-то еще, и я как-то пропустил это. Ваши советы и помощь будут очень благодарны!