Как R6 завершает каскадные объекты? - PullRequest
0 голосов
/ 30 января 2020

Извините за долгое вступление.

Люди из CRAN настоятельно рекомендовали написать тесты для моего пакета, и благодаря этим тестам я обнаружил, что где-то происходит сбой. При выполнении тестов я получаю следующий вывод:

Loading RBaseX
Testing RBaseX
✓ |  OK F W S | Context
✓ |   2       | test_first [0.1 s]
✓ |   8       | test_QueryClass
⠋ |   1       | test_RbaseX 
Database 'TestOpen' is niet gevonden. 
Database 'TestOpen' is niet gevonden. 
Database 'TestOpen' is niet gevonden. 
Database 'Testopen' is gesloten.

✓ |   5       | test_RbaseX [0.2 s]
⠏ |   0       | test_Wrappers 
✓ |   6       | test_Wrappers
⠦ |   6 1     | test_Wrappers
══ Results ════════════════════════════
Duration: 0.5 s

OK:       21
Failed:   1
Warnings: 0
Skipped:  0

После добавления новых тестов либо в новый тестовый файл, либо в существующий тестовый файл, в последней строке всегда отображается счетчик в F-столбце. имеет значение 1. Нет указания на причину сбоя.

Мой первый вопрос - как следует интерпретировать точки в первом столбце. Они дают информацию о причине?

Мои следующие вопросы касаются процесса finalize ().
Мой пакет основан на 3 классах R6:

  1. "BasexClient" основной класс
  2. «SocketClass»
  3. «QueryClass»

После инициализации экземпляр «SocketClass» используется для установления sh соединения с BaseX -сервер (XML -database). SocketClass также предоставляет функции для записи или чтения из соединения. Соединение закрывается в процессе finalize ().
Для более сложных запросов могут использоваться экземпляры из QueryClass. Каждый экземпляр этого QueryClass регистрируется в базе данных. При успешной регистрации ID возвращается. Этот идентификатор используется при взаимодействии с базой данных. Количество запросов, которые можно зарегистрировать, не ограничено. Ссылка на экземпляры QueryClass поддерживается в закрытом поле (списке) для BaseXClient.
Следующий код показывает, как создается новый сеанс и как добавляются два запроса:

Session <- BasexClient$new("localhost", 1984L, username = "admin", password = "admin")
Query_1 <- Session$Query("for $i in 1 to 2 return $i")
Query_2 <- Session$Query("for $i in 3 to 4 return $i")

str(Query_1) говорит мне структуру Query_1:

List of 2
$ queryObject:Classes 'QueryClass', 'R6' <QueryClass>
  Public:
    Bind: function (...) 
    clone: function (deep = FALSE) 
    Close: function () 
    Context: function (value, type) 
    ExecuteQuery: function () 
    Full: function () 
    Info: function () 
    initialize: function (query, Parent) 
    More: function () 
    Next: function () 
    Options: function () 
    Updating: function () 
  Private:
    cache: NULL
    clean: function (input) 
    default_query_pattern: function (Caller) 
    parent: BasexClient, R6
    pos: NULL
    raw_id: 31 00
    receive_more: function (input, output) 
    req_result: 
    sock: SocketClass, R6
    write_code_ID: function (id_code)  
 $ success    : logi TRUE

Один из методов для QueryClass - это Close (). Этот метод отменяет регистрацию запроса в базе данных.

Query_1$queryObject$Close()

Нет ограничения на количество зарегистрированных запросов, и нет способа гарантировать, что все запросы явно закрыты. Поэтому я хотел бы использовать finalize (), чтобы закрыть все запросы. Список со ссылками на зарегистрированные QueryInstances доступен как личное поле экземпляра BaseXClient. Я попробовал это:

finalize = function() {
  for (index in 1:length(private$QueryList)) {self$private$QueryList[index]$queryObject$Close()}
}

rm(Session) не дает ошибок, но testthat повторяется Error: attempt to apply non-function.
Мои вопросы:

  1. При использовании rm(Session), в в каком порядке будут завершены элементы BasexClient, SocketClass и QueryClass? Если сначала удалить SocketClass, то логично, что экземпляры QueryClass не могут быть закрыты, поскольку соединение с базой данных больше не существует.
  2. Как можно управлять порядком finalize ()?

Бен

...