optunity icon indicating copy to clipboard operation
optunity copied to clipboard

Win7 R installation won't start python standalone server

Open joelgraff opened this issue 10 years ago • 2 comments

After digging through several issues (one of which involved a missing path variable), the fault I'm encountering lies with the launch() function in comm.R.

Specifically,

launch <- function(){
  optunitydir <- dirname( system.file("optunity", package="optunity") )
  cmd <- sprintf("cd '%s'; python -m optunity.standalone server %s", optunitydir, ifelse(debug(), "", "2>/dev/null"))

  opipe <- pipe(cmd, open="r+")
  portstr <- readLines(opipe, n = 1)
  port    <- strtoi( gsub("^\\s+|\\s+$", "", portstr) )

  if (is.na(port) || port == 0) {
    stop("Optunity error: could not launch python process.")
  }

  ...
}

'optunitydir' is properly defined, and executing pipe() on cmd opens a connection as it should.

However, it appears opipe returns a python-specific object (a Win32 connection) and as such, cannot be operated on by the readLine() function, which inevitably leads to this error when R evaluates the conditional:

Error in if (is.na(port) || port == 0) { :  missing value where TRUE/FALSE needed

After inspecting what 'opipe' returns in R, it appears it returns a numeric vector of zeros, the number of which indicates the port number. Thus, the line:

port <- length(numeric(opipe))

will return the correct port number as an interger that can then be used in the call to socketConnection() and the construction of the returned 'conn' object.

My modification to comm::launch(), then, appears as follows:

launch <- function(){
  optunitydir <- dirname( system.file("optunity", package="optunity") )
  cmd <- sprintf("cd '%s'; python -m optunity.standalone server %s", optunitydir, ifelse(debug(), "", "2>/dev/null"))

  opipe <- pipe(cmd, open="r+")
  port <- length(numeric(opipe))

  if (is.na(port) || port == 0) {
    stop("Optunity error: could not launch python process.")
  }

  socket <- socketConnection(port = port, blocking = TRUE)
  conn   <- list(socket = socket, port = port, opipe = opipe)
  return (conn)
}

I would submit the changes in a pull request, but I don't have access to gihub from my machine, unfortunately.

joelgraff avatar Nov 04 '15 17:11 joelgraff

It seems the behavior of numeric(opipe) is not very reliable as in Linux it just returns vector of three 0s.

But there is a simple alternative. We can change optunity.standalone server to take an extra argument for a file name where to write the port number to.

@claesenm what do you think about this workaround for establishing communication between R and Python in Windows?

jaak-s avatar Nov 04 '15 18:11 jaak-s

@graffy76 thanks for the very detailed bug report! @jaak-s the workaround sounds okay. A possible alternative would be to check what OS we're running and then deal with it differently, but usually those approaches cause more issues than they solve.

claesenm avatar Nov 04 '15 18:11 claesenm