Skip to content

Commit a18a735

Browse files
committed
more consistent ncurl_session() behaviour
1 parent 35d6d3b commit a18a735

File tree

5 files changed

+24
-21
lines changed

5 files changed

+24
-21
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
* Send mode 'next' is folded into the default 'serial', with custom serialization functions applying automatically if they have been registered.
1515
* The session-wide `next_config()` is now deprecated and defunct, in favour of the new `serial_config()`.
16+
* `ncurl_session()` now returns 'errorValue' 7 (Object closed) when attempting to transact over a closed session or closing a closed session, rather than throwing an error.
1617
* `collect_aio()` and `collect_aio_()` no longer append empty names when acting on lists of Aios where there were none in the first place.
1718
* Removes hard dependency on `stats` and `utils` base packages.
1819
* Requires R >= 3.6.

R/socket.R

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,7 @@ collect_pipe <- function(x) .Call(rnng_aio_collect_pipe, x)
179179
#' will be terminated and any new operations will fail after the connection
180180
#' is closed.
181181
#'
182-
#' Closing an \sQuote{ncurlSession} closes any active http(s) connection and
183-
#' frees all related resources. The session is no longer active and cannot
184-
#' be re-used.
182+
#' Closing an \sQuote{ncurlSession} closes the http(s) connection.
185183
#'
186184
#' As Pipes are owned by the corresponding Socket, removing (and garbage
187185
#' collecting) a Pipe does not close it or free its resources. A Pipe may,

man/close.Rd

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ncurl.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ static void session_finalizer(SEXP xptr) {
135135
if (NANO_PTR(xptr) == NULL) return;
136136
nano_aio *xp = (nano_aio *) NANO_PTR(xptr);
137137
nano_handle *handle = (nano_handle *) xp->next;
138-
nng_http_conn *conn = (nng_http_conn *) xp->data;
139-
nng_http_conn_close(conn);
138+
if (xp->data != NULL)
139+
nng_http_conn_close((nng_http_conn *) xp->data);
140140
nng_aio_free(xp->aio);
141141
if (handle->cfg != NULL)
142142
nng_tls_config_free(handle->cfg);
@@ -659,9 +659,12 @@ SEXP rnng_ncurl_transact(SEXP session) {
659659
Rf_error("'session' is not a valid or active ncurlSession");
660660

661661
nano_aio *haio = (nano_aio *) NANO_PTR(session);
662+
663+
if (haio->data == NULL)
664+
return mk_error_ncurl(7);
665+
662666
nng_http_conn *conn = (nng_http_conn *) haio->data;
663667
nano_handle *handle = (nano_handle *) haio->next;
664-
665668
nng_http_conn_transact(conn, handle->req, handle->res, haio->aio);
666669
nng_aio_wait(haio->aio);
667670
if (haio->result > 0)
@@ -713,10 +716,13 @@ SEXP rnng_ncurl_session_close(SEXP session) {
713716
if (NANO_TAG(session) != nano_StatusSymbol)
714717
Rf_error("'session' is not a valid or active ncurlSession");
715718

716-
session_finalizer(session);
717-
NANO_SET_TAG(session, R_NilValue);
718-
NANO_SET_PROT(session, R_NilValue);
719-
R_ClearExternalPtr(session);
719+
nano_aio *haio = (nano_aio *) NANO_PTR(session);
720+
721+
if (haio->data == NULL)
722+
ERROR_RET(7);
723+
724+
nng_http_conn_close((nng_http_conn *) haio->data);
725+
haio->data = NULL;
720726
Rf_setAttrib(session, nano_StateSymbol, R_MissingArg);
721727

722728
return nano_success;

tests/tests.R

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ nanotestxp <- function(x) invisible(typeof(x) == "externalptr" || stop("is not o
1212
nanotesterr <- function(x, e = "")
1313
invisible(grepl(e, tryCatch(x, error = identity)[["message"]], fixed = TRUE) || stop("expected error message '", e, "' not generated"))
1414
later <- requireNamespace("later", quietly = TRUE)
15+
promises <- requireNamespace("promises", quietly = TRUE)
1516

1617
nng_version()
1718
nanotestnano(n <- nano("req", listen = "inproc://nanonext", autostart = FALSE))
@@ -408,11 +409,12 @@ sess <- ncurl_session("https://postman-echo.com/post", method = "POST", headers
408409
nanotest(is_ncurl_session(sess) || is_error_value(sess))
409410
if (is_ncurl_session(sess)) nanotest(length(transact(sess)) == 3L)
410411
if (is_ncurl_session(sess)) nanotest(close(sess) == 0L)
412+
if (is_ncurl_session(sess)) nanotestw(close(sess) == 7L)
411413
sess <- ncurl_session("https://postman-echo.com/post", convert = FALSE, method = "POST", headers = c(`Content-Type` = "text/plain"), timeout = 3000)
412414
nanotest(is_ncurl_session(sess) || is_error_value(sess))
413415
if (is_ncurl_session(sess)) nanotest(length(transact(sess)) == 3L)
414416
if (is_ncurl_session(sess)) nanotest(close(sess) == 0L)
415-
nanotesterr(transact(sess), "ncurlSession")
417+
if (is_ncurl_session(sess)) nanotest(transact(sess)$data == 7L)
416418
nanotestw(is_error_value(ncurl_session("https://i")))
417419
nanotesterr(ncurl_aio("https://", tls = "wrong"), "valid TLS")
418420
nanotesterr(ncurl("https://www.cam.ac.uk/", tls = "wrong"), "valid TLS")
@@ -595,13 +597,11 @@ nanotestw(listen(s, url = "tls+tcp://.", tls = tls, error = FALSE) > 0)
595597
nanotestz(close(s1))
596598
nanotestz(close(s))
597599
nanotest(!identical(get0(".Random.seed"), {.advance(); .Random.seed}))
598-
if (requireNamespace("promises", quietly = TRUE)) {
599-
nanotestaio(n <- ncurl_aio("https://postman-echo.com/get"))
600-
nanotest(tryCatch(promises::is.promise(promises::then(n, cat)), error = function(e) TRUE))
601-
nanotest(promises::is.promising(call_aio(n)))
602-
nanotest(promises::is.promise(promises::as.promise(call_aio(ncurl_aio("https://postman-echo.com/get")))))
603-
later::run_now()
604-
}
600+
if (promises) nanotestaio(n <- ncurl_aio("https://postman-echo.com/get"))
601+
if (promises) nanotest(tryCatch(promises::is.promise(promises::then(n, cat)), error = function(e) TRUE))
602+
if (promises) nanotest(promises::is.promising(call_aio(n)))
603+
if (promises) nanotest(promises::is.promise(promises::as.promise(call_aio(ncurl_aio("https://postman-echo.com/get")))))
604+
if (promises) later::run_now()
605605
if (Sys.info()[["sysname"]] == "Linux") {
606606
rm(list = ls())
607607
gc()

0 commit comments

Comments
 (0)