Skip to content

Commit d0ce795

Browse files
committed
More resilient req/rep RPC server behaviour
1 parent 7a27728 commit d0ce795

File tree

7 files changed

+43
-27
lines changed

7 files changed

+43
-27
lines changed

R/context.R

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ ctx_recv <- function(context,
165165
#' @param execute a function which takes the received (converted) data as its
166166
#' first argument. Can be an anonymous function of the form \code{function(x) do(x)}.
167167
#' Additional arguments can also be passed in through '...'.
168-
#' @param ... additional arguments passed to the function specified by 'execute'.
169168
#' @param send_mode [default 'serial'] whether data will be sent serialized or
170169
#' as a raw vector. Use 'serial' for sending and receiving within R to ensure
171170
#' perfect reproducibility. Use 'raw' for sending vectors of any type (will be
@@ -179,15 +178,17 @@ ctx_recv <- function(context,
179178
#' be used. Note this applies to each of the receive and send legs, hence the
180179
#' total elapsed time could be up to twice this parameter plus the time to
181180
#' perform 'execute' on the received data.
181+
#' @param ... additional arguments passed to the function specified by 'execute'.
182182
#'
183183
#' @return Invisible NULL.
184184
#'
185185
#' @details Async recv will block while awaiting a message to arrive and is
186186
#' usually the desired result. Set a timeout to allow the function to return
187187
#' if no data is forthcoming.
188188
#'
189-
#' In case of an error in unserialisation or data conversion, the function
190-
#' will return the received raw vector to allow the data to be recovered.
189+
#' In the event of an error in unserialisation or data conversion, or in the
190+
#' evaluation of the function with respect to the data, a NULL byte (or
191+
#' serialized NULL byte) will be sent in reply to signal an error to the client.
191192
#'
192193
#' @examples
193194
#' req <- socket("req", listen = "tcp://127.0.0.1:6546")
@@ -211,11 +212,11 @@ ctx_recv <- function(context,
211212
#'
212213
ctx_rep <- function(context,
213214
execute,
214-
...,
215215
recv_mode = c("serial", "character", "complex", "double",
216216
"integer", "logical", "numeric", "raw"),
217217
send_mode = c("serial", "raw"),
218-
timeout) {
218+
timeout,
219+
...) {
219220

220221
recv_mode <- match.arg(recv_mode)
221222
send_mode <- match.arg(send_mode)
@@ -225,14 +226,14 @@ ctx_rep <- function(context,
225226
message(res, " : ", nng_error(res))
226227
return(invisible(res))
227228
}
228-
on.exit(expr = return(res))
229+
on.exit(expr = send_aio(context, writeBin(object = "", con = raw()), mode = send_mode))
229230
data <- switch(recv_mode,
230231
serial = unserialize(connection = res),
231232
character = (r <- readBin(con = res, what = recv_mode, n = length(res)))[r != ""],
232233
raw = res,
233234
readBin(con = res, what = recv_mode, n = length(res)))
234-
on.exit(expr = NULL)
235235
msg <- execute(data, ...)
236+
on.exit(expr = NULL)
236237
ctx_send(context, data = msg, mode = send_mode, timeout = timeout, echo = FALSE)
237238

238239
}
@@ -260,6 +261,9 @@ ctx_rep <- function(context,
260261
#' In case of an error in unserialisation or data conversion, the function
261262
#' will return the received raw vector to allow the data to be recovered.
262263
#'
264+
#' If an error occured in the server process, a NULL byte will be received
265+
#' (as \code{$data} if 'recv_mode' = 'serial', as \code{$raw} otherwise).
266+
#'
263267
#' @examples
264268
#' req <- socket("req", listen = "tcp://127.0.0.1:6546")
265269
#' rep <- socket("rep", dial = "tcp://127.0.0.1:6546")

R/docs.R

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ NULL
122122
#' tries hard to avoid copying data, and thus is very light-weight.
123123
#'
124124
#' [\strong{URI, inproc://}] This transport uses URIs using the scheme inproc://,
125-
#' followed by an arbitrary string of text, terminated by a NUL byte.
125+
#' followed by an arbitrary string of text, terminated by a NULL byte.
126+
#' inproc://nanonext is a valid example URL.
126127
#'
127128
#' \itemize{
128129
#' \item Multiple URIs can be used within the same application, and they will
@@ -147,10 +148,14 @@ NULL
147148
#' followed by a path name in the file system where the socket or named pipe
148149
#' should be created.
149150
#' \itemize{
151+
#' \item On POSIX platforms, the path is taken literally, and is relative to
152+
#' the current directory, unless it begins with /, in which case it is
153+
#' relative to the root directory. For example, ipc://nanonext refers to the
154+
#' name nanonext in the current directory, whereas ipc:///tmp/nanonext
155+
#' refers to nanonext located in /tmp.
150156
#' \item On Windows, all names are prefixed by \\.\ pipe\ and do not reside
151-
#' in the normal file system. On POSIX platforms, the path is taken literally,
152-
#' and is relative to the current directory, unless it begins with /, in
153-
#' which case it is relative to the root directory.
157+
#' in the normal file system - the required prefix is added automatically
158+
#' by NNG, so you should specify a URL such as ipc://nanonext directly.
154159
#' }
155160
#'
156161
#' \emph{UNIX Aliases}
@@ -166,8 +171,7 @@ NULL
166171
#' [\strong{URI, abstract://}] On Linux, this transport also can support abstract
167172
#' sockets. Abstract sockets use a URI-encoded name after the scheme,
168173
#' which allows arbitrary values to be conveyed in the path, including
169-
#' embedded NUL bytes. For example, the name "a\0b" would be represented as
170-
#' abstract://a%00b.
174+
#' embedded NULL bytes. abstract://nanonext is a valid example URL.
171175
#'
172176
#' \itemize{
173177
#' \item Abstract sockets do not have any representation in the file system,

R/utils.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ nng_error <- function(error) {
4747

4848
#' Timer Utility
4949
#'
50-
#' Set a timer (stopwatch). Will print a message to the console (stdout) upon
50+
#' Set a timer (stopwatch). Will print a message to the console (stderr) upon
5151
#' completion.
5252
#'
5353
#' @param time time in ms. Non-integer values will be translated to integer using

man/ctx_rep.Rd

Lines changed: 7 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/ctx_req.Rd

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

man/nng_timer.Rd

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

man/transports.Rd

Lines changed: 10 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)