File: isConnectionValid.Rd

package info (click to toggle)
r-cran-parallelly 1.42.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,216 kB
  • sloc: ansic: 111; sh: 13; makefile: 2
file content (116 lines) | stat: -rw-r--r-- 5,417 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/isConnectionValid.R
\name{isConnectionValid}
\alias{isConnectionValid}
\alias{connectionId}
\title{Checks if a Connection is Valid}
\usage{
isConnectionValid(con)

connectionId(con)
}
\arguments{
\item{con}{A \link[base:connections]{connection}.}
}
\value{
\code{isConnectionValid()} returns TRUE if the connection is still valid,
otherwise FALSE.  If FALSE, then character attribute \code{reason} provides
an explanation why the connection is not valid.

\code{connectionId()} returns an non-negative integer, -1, or \code{NA_integer_}.
For connections stdin, stdout, and stderr, 0, 1, and 2, are returned,
respectively.  For all other connections, an integer greater or equal to
3 based on the connection's internal pointer is returned.
A connection that has been serialized, which is no longer valid, has
identifier -1.
Attribute \code{raw_id} returns the pointer string from which the above is
inferred.
}
\description{
Get a unique identifier for an R \link[base:connections]{connection}
and check whether or not the connection is still valid.
}
\section{Connection Index versus Connection Identifier}{

R represents \link[base:connections]{connections} as indices using plain
integers, e.g. \code{idx <- as.integer(con)}.
The three connections standard input ("stdin"), standard output ("stdout"),
and standard error ("stderr") always exists and have indices 0, 1, and 2.
Any connection opened beyond these will get index three or greater,
depending on availability as given by \code{\link[base:showConnections]{base::showConnections()}}.
To get the connection with a given index, use \code{\link[base:showConnections]{base::getConnection()}}.
\strong{Unfortunately, this index representation of connections is non-robust},
e.g. there are cases where two or more 'connection' objects can end up with
the same index and if used, the written output may end up at the wrong
destination and files and database might get corrupted.  This can for
instance happen if \code{\link[base:showConnections]{base::closeAllConnections()}} is used (*).
\strong{In contrast, \code{id <- connectionId(con)} gives an identifier that is unique
to that 'connection' object.}  This identifier is based on the internal
pointer address of the object.  The risk for two connections in the same
\R session to end up with the same pointer address is very small.
Thus, in case we ended up in a situation where two connections \code{con1} and
\code{con2} share the same index---\code{as.integer(con1) == as.integer(con2)}---
they will never share the same identifier---
\code{connectionId(con1) != connectionId(con2)}.
Here, \code{isConnectionValid()} can be used to check which one of these
connections, if any, are valid.

(*) Note that there is no good reason for calling \code{closeAllConnections()}
If called, there is a great risk that the files get corrupted etc.
See (1) for examples and details on this problem.
If you think there is a need to use it, it is much safer to restart \R
because that is guaranteed to give you a working \R session with
non-clashing connections.
It might also be that \code{closeAllConnections()} is used because
\code{\link[base:base-internal]{base::sys.save.image()}} is called, which might happen if \R is being
forced to terminate.
}

\section{Connections Cannot be Serialized Or Saved}{

A 'connection' cannot be serialized, e.g. it cannot be saved to file to
be read and used in another \R session.  If attempted, the connection will
not be valid.  This is a problem that may occur in parallel processing
when passing an \R object to parallel worker for further processing, e.g.
the exported object may hold an internal database connection which will
no longer be valid on the worker.
When a connection is serialized, its internal pointer address will be
invalidated (set to nil). In such cases, \code{connectionId(con)} returns -1
and \code{isConnectionValid(con)} returns FALSE.
}

\examples{
## R represents connections as plain indices
as.integer(stdin())          ## int 0
as.integer(stdout())         ## int 1
as.integer(stderr())         ## int 2

## The first three connections always exist and are always valid
isConnectionValid(stdin())   ## TRUE
connectionId(stdin())        ## 0L
isConnectionValid(stdout())  ## TRUE
connectionId(stdout())       ## 1L
isConnectionValid(stderr())  ## TRUE
connectionId(stderr())       ## 2L

## Connections cannot be serialized
con <- file(tempfile(), open = "w")
x <- list(value = 42, stderr = stderr(), con = con)
y <- unserialize(serialize(x, connection = NULL))
isConnectionValid(y$stderr)  ## TRUE
connectionId(y$stderr)       ##  2L
isConnectionValid(y$con)     ## FALSE with attribute 'reason'
connectionId(y$con)          ## -1L
close(con)

}
\references{
\enumerate{
\item \href{https://github.com/HenrikBengtsson/Wishlist-for-R/issues/81}{'BUG: A \code{connection} object may become corrupt and re-referenced to another connection (PATCH)'}, 2018-10-30.
\item R-devel thread \href{https://stat.ethz.ch/pipermail/r-devel/2018-October/077004.html}{PATCH: Asserting that 'connection' used has not changed + R_GetConnection2()}, 2018-10-31.
}
}
\seealso{
See \code{\link[base:showConnections]{base::showConnections()}} for currently open connections and their
indices. To get a connection by its index, use \code{\link[base:showConnections]{base::getConnection()}}.
}