Skip to content

Commit 3c08760

Browse files
committed
Automatically detect libmbedtls
1 parent b69edeb commit 3c08760

File tree

8 files changed

+166
-131
lines changed

8 files changed

+166
-131
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* Common format for NNG errors and informational events now starts with a timestamp for easier logging.
1919
* Allows setting the environment variable 'NANONEXT_ARM' prior to package installation
2020
+ Fixes installation issues on certain ARM architectures
21+
* Package installation using a system 'libnng' now automatically detects 'libmbedtls', removing the need to manually set 'NANONEXT_TLS' in this case.
2122
* More streamlined NNG build process eliminating unused options.
2223
* Removes experimental `nng_timer()` utility as a non-essential function.
2324
* Deprecated functions 'send_vec' and 'recv_vec' removed.

R/aio.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ stop_aio <- function(aio) {
123123
#'
124124
unresolved <- function(aio) {
125125

126-
{inherits(aio, "unresolvedExpr") && inherits(.subset2(aio, "data"), "unresolvedValue") ||
126+
{inherits(aio, "unresolvedExpr") && inherits(.subset2(aio, "data"), "unresolvedExpr") ||
127127
inherits(aio, "unresolvedValue") ||
128128
inherits(aio, "recvAio") && inherits(.subset2(aio, "data"), "unresolvedValue") ||
129129
inherits(aio, "sendAio") && inherits(.subset2(aio, "result"), "unresolvedValue")} &&

R/pipe.R

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# nanonext - Deferred Evaluation Pipe ------------------------------------------
2+
3+
#' Deferred Evaluation Pipe
4+
#'
5+
#' Pipe a possibly unresolved value forward into a function.
6+
#'
7+
#' @param x a value that is possibly an 'unresolvedValue'.
8+
#' @param f a function that accepts 'x' as its first argument.
9+
#'
10+
#' @return The evaluated result, or if x is an 'unresolvedValue', an
11+
#' 'unresolvedExpr'.
12+
#'
13+
#' @details An 'unresolvedExpr' encapsulates the eventual evaluation result.
14+
#' Query its \code{$data} element for resolution. Once resolved, the object
15+
#' changes into a 'resolvedExpr' and the evaluated result will be available
16+
#' at \code{$data}.
17+
#'
18+
#' Supports stringing together a series of piped expressions (as per
19+
#' the below example).
20+
#'
21+
#' \code{\link{unresolved}} may be used on an 'unresolvedExpr' or its
22+
#' \code{$data} element to test for resolution.
23+
#'
24+
#' This function is marked [experimental], which means it is currently
25+
#' under development. Please note that the final implementation is likely to
26+
#' differ from the current version.
27+
#'
28+
#' @section Usage:
29+
#'
30+
#' Usage is similar to R's native \code{|>} pipe.
31+
#'
32+
#' \code{x \%>>\% f} is equivalent to \code{f(x)}
33+
#'
34+
#' \code{x \%>>\% f()} is equivalent to \code{f(x)}
35+
#'
36+
#' \code{x \%>>\% f(y)} is equivalent to \code{f(x, y)}
37+
#'
38+
#' Please note that other usage is not supported and it is not a drop-in
39+
#' replacement for magrittr's \code{\%>\%} pipe.
40+
#'
41+
#' @examples
42+
#' if (interactive()) {
43+
#' # Only run examples in interactive R sessions
44+
#'
45+
#' s1 <- socket("pair", listen = "inproc://nanonext")
46+
#' s2 <- socket("pair", dial = "inproc://nanonext")
47+
#'
48+
#' msg <- recv_aio(s2)
49+
#' b <- msg$data %>>% c(2, 3) %>>% as.character()
50+
#' b
51+
#' res <- send_aio(s1, 1)
52+
#' b$data
53+
#'
54+
#' close(s1)
55+
#' close(s2)
56+
#' }
57+
#'
58+
#' @export
59+
#'
60+
`%>>%` <- function(x, f) {
61+
if (unresolved(x)) {
62+
mc <- match.call()
63+
data <- NULL
64+
env <- `class<-`(new.env(), c("unresolvedExpr"))
65+
makeActiveBinding(sym = "data", fun = function(x) {
66+
if (is.null(data)) data <- eval(mc, envir = parent.frame(), enclos = baseenv())
67+
if (!inherits(data, "unresolvedExpr")) `class<-`(env, "resolvedExpr")
68+
data
69+
}, env = env)
70+
env
71+
} else {
72+
x <- substitute(x)
73+
y <- substitute(f)
74+
if (is.symbol(y)) {
75+
eval(as.call(c(y, x)), envir = parent.frame(2L), enclos = baseenv())
76+
} else {
77+
f <- y[[1L]]
78+
y[[1L]] <- NULL
79+
eval(as.call(c(f, x, y)), envir = parent.frame(2L), enclos = baseenv())
80+
}
81+
}
82+
}
83+
84+
#' @export
85+
#'
86+
print.unresolvedExpr <- function(x, ...) {
87+
cat("< unresolvedExpr >\n - $data to query resolution\n", file = stdout())
88+
invisible(x)
89+
}
90+
91+
#' @export
92+
#'
93+
print.resolvedExpr <- function(x, ...) {
94+
cat("< resolvedExpr: $data >\n", file = stdout())
95+
invisible(x)
96+
}
97+

R/utils.R

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -217,95 +217,3 @@ ncurl <- function(http, ...) {
217217

218218
}
219219

220-
#' Deferred Evaluation Pipe
221-
#'
222-
#' Pipe a possibly unresolved value forward into a function.
223-
#'
224-
#' @param x a value that is possibly an 'unresolvedValue'.
225-
#' @param f a function that accepts 'x' as its first argument.
226-
#'
227-
#' @return The evaluated result, or if x is an 'unresolvedValue', an
228-
#' 'unresolvedExpr'.
229-
#'
230-
#' @details An 'unresolvedExpr' encapsulates the eventual evaluation result.
231-
#' Query its \code{$data} element for resolution. Once resolved, the object
232-
#' will change to a 'resolvedExpr' and the evaluated result will be accessible
233-
#' at \code{$data}.
234-
#'
235-
#' Supports stringing together a series of piped expressions (as per
236-
#' the below example).
237-
#'
238-
#' \code{\link{unresolved}} may be used on an 'unresolvedExpr' or its
239-
#' \code{$data} element to test for resolution.
240-
#'
241-
#' This function is marked [experimental], which means it is currently
242-
#' under development. Please note that the final implementation is likely to
243-
#' differ from the current version.
244-
#'
245-
#' @section Usage:
246-
#'
247-
#' \code{x \%>>\% f} is equivalent to \code{f(x)}
248-
#'
249-
#' \code{x \%>>\% f()} is equivalent to \code{f(x)}
250-
#'
251-
#' \code{x \%>>\% f(y)} is equivalent to \code{f(x, y)}
252-
#'
253-
#' @examples
254-
#' if (interactive()) {
255-
#' # Only run examples in interactive R sessions
256-
#'
257-
#' s1 <- socket("pair", listen = "inproc://nanonext")
258-
#' s2 <- socket("pair", dial = "inproc://nanonext")
259-
#'
260-
#' msg <- recv_aio(s2)
261-
#' b <- msg$data %>>% c(2, 3) %>>% as.character()
262-
#' b
263-
#' res <- send_aio(s1, 1)
264-
#' b$data
265-
#'
266-
#' close(s1)
267-
#' close(s2)
268-
#' }
269-
#'
270-
#' @export
271-
#'
272-
`%>>%` <- function(x, f) {
273-
if (unresolved(x)) {
274-
mc <- match.call()
275-
data <- NULL
276-
env <- `class<-`(new.env(), c("unresolvedExpr", "unresolvedValue"))
277-
makeActiveBinding(sym = "data", fun = function(x) {
278-
if (is.null(data)) data <- eval(mc, envir = parent.frame(), enclos = baseenv())
279-
if (!inherits(data, "unresolvedExpr")) `class<-`(env, "resolvedExpr")
280-
data
281-
}, env = env)
282-
env
283-
} else {
284-
x <- substitute(x)
285-
y <- substitute(f)
286-
if (is.symbol(y)) {
287-
eval(as.call(c(y, x)), envir = parent.frame(2L), enclos = baseenv())
288-
} else {
289-
f <- y[[1L]]
290-
y[[1L]] <- NULL
291-
eval(as.call(c(f, x, y)), envir = parent.frame(2L), enclos = baseenv())
292-
}
293-
}
294-
}
295-
296-
#' @export
297-
#'
298-
print.unresolvedExpr <- function(x, ...) {
299-
cat("< unresolvedExpr >\n - $data to query resolution\n", file = stdout())
300-
invisible(x)
301-
}
302-
303-
#' @export
304-
#'
305-
print.resolvedExpr <- function(x, ...) {
306-
cat("< resolvedExpr >\n - $data for evaluated expression\n", file = stdout())
307-
invisible(x)
308-
}
309-
310-
311-

README.Rmd

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,9 @@ close(s2)
261261

262262
Simply pipe the value forward into a function or series of functions and it either evaluates or returns an 'unresolvedExpr'.
263263

264-
The result may be queried at `$data`, which will return another 'unresolvedExpr' recursively (by design) whilst unresolved. However when the original value resolves, the 'unresolvedExpr' will resolve into a 'resolvedExpr' and the evaluated expression may then be accessed at \code{$data}.
264+
The result may be queried at `$data`, which will return another 'unresolvedExpr' whilst unresolved. However when the original value resolves, the 'unresolvedExpr' will simultaneously resolve into a 'resolvedExpr', for which the evaluated result will be available at `$data`.
265265

266-
It is possible to use `unresolved()` around a 'unresolvedExpr' or its `$data` field to test for resolution, as in the example below.
266+
It is possible to use `unresolved()` around a 'unresolvedExpr' or its `$data` element to test for resolution, as in the example below.
267267

268268
The pipe operator semantics are similar to R's base pipe `|>`:
269269

@@ -480,7 +480,9 @@ Pre-built libraries (for i386 / x64 / x64-UCRT) are automatically downloaded dur
480480

481481
#### TLS Support
482482

483-
If your system installation of NNG was built with TLS support (using Mbed TLS), please set the environment variable `Sys.setenv(NANONEXT_TLS=1)` before attempting to install the package. This will ensure the correct linker flags are set for a successful install.
483+
If a system installation of 'libnng' and 'libmbedtls' development headers are both detected in the same location, it is assumed that NNG was built with TLS support (using Mbed TLS) and the appropriate options are set to ensure a successful install.
484+
485+
If your system installation of NNG was built with TLS support (using Mbed TLS) but detection of 'libmbedtls' failed (possibly as it was installed in another location), you may also set the environment variable `Sys.setenv(NANONEXT_TLS=1)` before installing the package to ensure that the appropriate options are set.
484486

485487
#### Certain ARM architectures
486488

README.md

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -330,12 +330,13 @@ Simply pipe the value forward into a function or series of functions and
330330
it either evaluates or returns an ‘unresolvedExpr’.
331331

332332
The result may be queried at `$data`, which will return another
333-
‘unresolvedExpr’ recursively (by design) whilst unresolved. However when
334-
the original value resolves, the ‘unresolvedExpr’ will resolve into a
335-
‘resolvedExpr’ and the evaluated expression may then be accessed at .
333+
‘unresolvedExpr’ whilst unresolved. However when the original value
334+
resolves, the ‘unresolvedExpr’ will simultaneously resolve into a
335+
‘resolvedExpr’, for which the evaluated result will be available at
336+
`$data`.
336337

337338
It is possible to use `unresolved()` around a ‘unresolvedExpr’ or its
338-
`$data` field to test for resolution, as in the example below.
339+
`$data` element to test for resolution, as in the example below.
339340

340341
The pipe operator semantics are similar to R’s base pipe `|>`:
341342

@@ -361,8 +362,7 @@ s <- send_aio(s1, 1)
361362
unresolved(res)
362363
#> [1] FALSE
363364
res
364-
#> < resolvedExpr >
365-
#> - $data for evaluated expression
365+
#> < resolvedExpr: $data >
366366
res$data
367367
#> [1] "1" "2" "3"
368368

@@ -421,7 +421,7 @@ aio
421421
#> < recvAio >
422422
#> - $data for message data
423423
aio$data |> str()
424-
#> num [1:100000000] -0.149 1.493 -1.299 1.694 1.856 ...
424+
#> num [1:100000000] -0.82 0.147 1.761 0.425 0.182 ...
425425
```
426426

427427
As `call_aio()` is blocking and will wait for completion, an alternative
@@ -456,37 +456,37 @@ an environment variable `NANONEXT_LOG`.
456456

457457
``` r
458458
logging(level = "info")
459-
#> 2022-03-07 00:33:28 [ log level ] set to: info
459+
#> 2022-03-07 22:11:21 [ log level ] set to: info
460460

461461
pub <- socket("pub", listen = "inproc://nanobroadcast")
462-
#> 2022-03-07 00:33:28 [ sock open ] id: 11 | protocol: pub
463-
#> 2022-03-07 00:33:28 [ list start ] sock: 11 | url: inproc://nanobroadcast
462+
#> 2022-03-07 22:11:21 [ sock open ] id: 11 | protocol: pub
463+
#> 2022-03-07 22:11:21 [ list start ] sock: 11 | url: inproc://nanobroadcast
464464
sub <- socket("sub", dial = "inproc://nanobroadcast")
465-
#> 2022-03-07 00:33:28 [ sock open ] id: 12 | protocol: sub
466-
#> 2022-03-07 00:33:28 [ dial start ] sock: 12 | url: inproc://nanobroadcast
465+
#> 2022-03-07 22:11:21 [ sock open ] id: 12 | protocol: sub
466+
#> 2022-03-07 22:11:21 [ dial start ] sock: 12 | url: inproc://nanobroadcast
467467

468468
sub |> subscribe(topic = "examples")
469-
#> 2022-03-07 00:33:28 [ subscribe ] sock: 12 | topic: examples
469+
#> 2022-03-07 22:11:21 [ subscribe ] sock: 12 | topic: examples
470470
pub |> send(c("examples", "this is an example"), mode = "raw", echo = FALSE)
471471
sub |> recv(mode = "character", keep.raw = FALSE)
472472
#> [1] "examples" "this is an example"
473473

474474
pub |> send(c("other", "this other topic will not be received"), mode = "raw", echo = FALSE)
475475
sub |> recv(mode = "character", keep.raw = FALSE)
476-
#> 2022-03-07 00:33:28 [ 8 ] Try again
476+
#> 2022-03-07 22:11:21 [ 8 ] Try again
477477

478478
# specify NULL to subscribe to ALL topics
479479
sub |> subscribe(topic = NULL)
480-
#> 2022-03-07 00:33:28 [ subscribe ] sock: 12 | topic: ALL
480+
#> 2022-03-07 22:11:21 [ subscribe ] sock: 12 | topic: ALL
481481
pub |> send(c("newTopic", "this is a new topic"), mode = "raw", echo = FALSE)
482482
sub |> recv("character", keep.raw = FALSE)
483483
#> [1] "newTopic" "this is a new topic"
484484

485485
sub |> unsubscribe(topic = NULL)
486-
#> 2022-03-07 00:33:28 [ unsubscribe ] sock: 12 | topic: ALL
486+
#> 2022-03-07 22:11:21 [ unsubscribe ] sock: 12 | topic: ALL
487487
pub |> send(c("newTopic", "this topic will now not be received"), mode = "raw", echo = FALSE)
488488
sub |> recv("character", keep.raw = FALSE)
489-
#> 2022-03-07 00:33:28 [ 8 ] Try again
489+
#> 2022-03-07 22:11:21 [ 8 ] Try again
490490

491491
# however the topics explicitly subscribed to are still received
492492
pub |> send(c("examples", "this example will still be received"), mode = "raw", echo = FALSE)
@@ -495,7 +495,7 @@ sub |> recv(mode = "character", keep.raw = FALSE)
495495

496496
# set logging level back to the default of errors only
497497
logging(level = "error")
498-
#> 2022-03-07 00:33:28 [ log level ] set to: error
498+
#> 2022-03-07 22:11:21 [ log level ] set to: error
499499

500500
close(pub)
501501
close(sub)
@@ -546,7 +546,7 @@ aio2$data
546546
# after the survey expires, the second resolves into a timeout error
547547
Sys.sleep(0.5)
548548
aio2$data
549-
#> 2022-03-07 00:33:29 [ 5 ] Timed out
549+
#> 2022-03-07 22:11:22 [ 5 ] Timed out
550550
#> 'errorValue' int 5
551551

552552
close(sur)
@@ -572,11 +572,11 @@ ncurl("http://httpbin.org/headers")
572572
#> [1] 7b 0a 20 20 22 68 65 61 64 65 72 73 22 3a 20 7b 0a 20 20 20 20 22 48 6f 73
573573
#> [26] 74 22 3a 20 22 68 74 74 70 62 69 6e 2e 6f 72 67 22 2c 20 0a 20 20 20 20 22
574574
#> [51] 58 2d 41 6d 7a 6e 2d 54 72 61 63 65 2d 49 64 22 3a 20 22 52 6f 6f 74 3d 31
575-
#> [76] 2d 36 32 32 35 35 32 64 39 2d 33 65 32 38 34 66 63 30 36 37 62 65 37 32 65
576-
#> [101] 63 33 66 61 61 34 65 30 34 22 0a 20 20 7d 0a 7d 0a
575+
#> [76] 2d 36 32 32 36 38 33 30 61 2d 33 61 62 32 30 31 39 64 35 34 64 33 66 63 66
576+
#> [101] 30 32 37 30 39 66 62 62 32 22 0a 20 20 7d 0a 7d 0a
577577
#>
578578
#> $data
579-
#> [1] "{\n \"headers\": {\n \"Host\": \"httpbin.org\", \n \"X-Amzn-Trace-Id\": \"Root=1-622552d9-3e284fc067be72ec3faa4e04\"\n }\n}\n"
579+
#> [1] "{\n \"headers\": {\n \"Host\": \"httpbin.org\", \n \"X-Amzn-Trace-Id\": \"Root=1-6226830a-3ab2019d54d3fcf02709fbb2\"\n }\n}\n"
580580
```
581581

582582
For advanced use, supports additional HTTP methods such as POST or PUT.
@@ -611,11 +611,16 @@ downloaded during the package installation process.
611611

612612
#### TLS Support
613613

614+
If a system installation of ‘libnng’ and ‘libmbedtls’ development
615+
headers are both detected in the same location, it is assumed that NNG
616+
was built with TLS support (using Mbed TLS) and the appropriate options
617+
are set to ensure a successful install.
618+
614619
If your system installation of NNG was built with TLS support (using
615-
Mbed TLS), please set the environment variable
616-
`Sys.setenv(NANONEXT_TLS=1)` before attempting to install the package.
617-
This will ensure the correct linker flags are set for a successful
618-
install.
620+
Mbed TLS) but detection of ‘libmbedtls’ failed (possibly as it was
621+
installed in another location), you may also set the environment
622+
variable `Sys.setenv(NANONEXT_TLS=1)` before installing the package to
623+
ensure that the appropriate options are set.
619624

620625
#### Certain ARM architectures
621626

0 commit comments

Comments
 (0)