[Rd] cannot destroy connection (?) created by readLines in a tryCatch
luke-tierney at uiowa.edu
luke-tierney at uiowa.edu
Fri Dec 15 00:46:25 CET 2017
This has nothing to do with on.exit. It is an iteraction between where
the warning is signaled in 'file' and your _exiting_ warning handler.
This combination has the same issue,
tryCatch(file(tempfile(), "r"), warning = identity)
showConnections(all = TRUE)
as does
options(warn=2)
file(tempfile(), "r")
showConnections(all = TRUE)
I haven't looked at the internals of 'file' but it looks like
what it does is
add an entry to connections table
warn about non-existent file
realize it has to fail
remove the connections table entry
signal an error
This misses the possibility that the warning can result in a jump
if it is turned into a error or handled by an exiting handler.
It's worth filing a bug report on 'file'.
It's not clear what you are really trying to do, but establishing
an _exiting_ handler for warnings is usually not what you
want. If you are trying to suppress warnings you need to use a
calling handler, e.g. via suppressWarnings. If you want to do
something more sophisticated that does not terminate the
computation on a warniing you can build on what suppressWarnigns
does.
Best,
luke
On Thu, 14 Dec 2017, Gábor Csárdi wrote:
> On Thu, Dec 14, 2017 at 7:56 PM, Gabriel Becker <gmbecker at ucdavis.edu> wrote:
>> Gabor,
>>
>> You can grab the connection and destroy it via getConnection and then a
>> standard close call.
>
> Yeah, that's often a possible workaround, but since this connection
> was opened by
> readLines() internally, I don't necessarily know which one it is. E.g.
> I might open multiple
> connections to the same file, so I can't choose based on the file name.
>
> Btw. this workaround seems to work for me:
>
> read_lines <- function(con, ...) {
> if (is.character(con)) {
> con <- file(con)
> on.exit(close(con))
> }
> readLines(con, ...)
> }
>
> This is basically the same as readLines(), but on.exit() does its job here.
> That's another clue that it might be an on.exit() issue. Wild guess:
> on.exit() does not run if an internal function errors.
>
>> (it actually lists that it is "closed" already, but
>> still in the set of existing connections. I can't speak to that difference).
>
> It is closed but not destroyed.
>
> G.
>
>>> tryCatch(
>>
>> + readLines(tempfile(), warn = FALSE)[1],
>>
>> + error = function(e) NA,
>>
>> + warning = function(w) NA
>>
>> + )
>>
>> [1] NA
>>
>>> rm(list=ls(all.names = TRUE))
>>
>>> gc()
>>
>> used (Mb) gc trigger (Mb) max used (Mb)
>>
>> Ncells 257895 13.8 592000 31.7 416371 22.3
>>
>> Vcells 536411 4.1 8388608 64.0 1795667 13.7
>>
>>>
>>
>>> showConnections(all = TRUE)
>>
>> description
>>
>> 0 "stdin"
>>
>> 1 "stdout"
>>
>> 2 "stderr"
>>
>> 3
>> "/var/folders/79/l_n_5qr152d2d9d9xs0591lh0000gn/T//RtmpZRcxmh/file128a13bffc77"
>>
>> class mode text isopen can read can write
>>
>> 0 "terminal" "r" "text" "opened" "yes" "no"
>>
>> 1 "terminal" "w" "text" "opened" "no" "yes"
>>
>> 2 "terminal" "w" "text" "opened" "no" "yes"
>>
>> 3 "file" "r" "text" "closed" "yes" "yes"
>>
>>> con = getConnection(3)
>>
>>> con
>>
>> A connection with
>>
>> description
>> "/var/folders/79/l_n_5qr152d2d9d9xs0591lh0000gn/T//RtmpZRcxmh/file128a13bffc77"
>>
>> class "file"
>>
>> mode "r"
>>
>> text "text"
>>
>> opened "closed"
>>
>> can read "yes"
>>
>> can write "yes"
>>
>>> close(con)
>>
>>> showConnections(all=TRUE)
>>
>> description class mode text isopen can read can write
>>
>> 0 "stdin" "terminal" "r" "text" "opened" "yes" "no"
>>
>> 1 "stdout" "terminal" "w" "text" "opened" "no" "yes"
>>
>> 2 "stderr" "terminal" "w" "text" "opened" "no" "yes"
>>
>>
>>
>> HTH,
>> ~G
>>
>> On Thu, Dec 14, 2017 at 10:02 AM, Gábor Csárdi <csardi.gabor at gmail.com>
>> wrote:
>>>
>>> Consider this code. This is R 3.4.2, but based on a quick look at the
>>> NEWS, this has not been fixed.
>>>
>>> tryCatch(
>>> readLines(tempfile(), warn = FALSE)[1],
>>> error = function(e) NA,
>>> warning = function(w) NA
>>> )
>>>
>>> rm(list=ls(all.names = TRUE))
>>> gc()
>>>
>>> showConnections(all = TRUE)
>>>
>>> If you run it, you'll get a connection you cannot close(), i.e. the
>>> last showConnections() call prints:
>>>
>>> ❯ showConnections(all = TRUE)
>>> description
>>> 0 "stdin"
>>> 1 "stdout"
>>> 2 "stderr"
>>> 3
>>> "/var/folders/59/0gkmw1yj2w7bf2dfc3jznv5w0000gn/T//Rtmpc7JqVS/filecc2044b2ccec"
>>> class mode text isopen can read can write
>>> 0 "terminal" "r" "text" "opened" "yes" "no"
>>> 1 "terminal" "w" "text" "opened" "no" "yes"
>>> 2 "terminal" "w" "text" "opened" "no" "yes"
>>> 3 "file" "r" "text" "closed" "yes" "yes"
>>>
>>> AFAICT, readLines should close the connection:
>>>
>>> ❯ readLines
>>> function (con = stdin(), n = -1L, ok = TRUE, warn = TRUE, encoding =
>>> "unknown",
>>> skipNul = FALSE)
>>> {
>>> if (is.character(con)) {
>>> con <- file(con, "r")
>>> on.exit(close(con))
>>> }
>>> .Internal(readLines(con, n, ok, warn, encoding, skipNul))
>>> }
>>> <environment: namespace:base>
>>>
>>> so maybe this just a symptom of an on.exit() issue?
>>>
>>> Or am I missing something and it is possible to close the connection?
>>>
>>> Thanks,
>>> Gabor
>>>
>>> ______________________________________________
>>> R-devel at r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>
>>
>>
>> --
>> Gabriel Becker, PhD
>> Scientist (Bioinformatics)
>> Genentech Research
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
--
Luke Tierney
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa Phone: 319-335-3386
Department of Statistics and Fax: 319-335-3017
Actuarial Science
241 Schaeffer Hall email: luke-tierney at uiowa.edu
Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu
More information about the R-devel
mailing list