-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for interacting with Remote R sessions #109
Conversation
I'm happy to merge this (especially if @hmansell agrees!) but I'm not really sure if the current version is all that practically usable - mainly because I think that having to write e.g. I had two thoughts how to make this a bit more usable in the current version (it'll be much nicer when extension methods are supported - but even then, we might want to support alternative way for people with older F#). Using local R for discoveryOne option would be to use local installation of R for discovery of packages and remote R for execution. This should work nicely in the BM use case (when people want to connect to R session on local machine running in a GUI). You still need to have R locally, but you could write e.g.:
Allow opening packagesAnother option would be to allow opening packages by specifying their names in static parameters. This is quite similar to what you have but it makes the syntax more compatible:
Config fileThe other option would be to look for some local config file and then you'd get exactly the same API as currently, but I think nobody was very enthusiastic about this option. One thing I think would be useful would be to separate the remote R connection at compile-time and at run-time - see my example with I sketched this above - where |
@tpetricek I have a branch in my fork that implements exactly the comma-separated package syntax you describe above. It works nicely, but, is a bit strange. I like the option above it much better. Perhaps the use of a global, mutable, session could be made more explicit? I can see two useful approaches. Set global session once, explicitly// SetRemoteSession() establishes the remote session to use, instead of a
// local R session, in global mutable state.
R.SetRemoteSession("localhost", 12345) Scoped use of remote session// InRemoteSession() creates and uses the remote session for the scope of the
// provided function, disposes of the remote session when completed.
let result = R.InRemoteSession("localhost", 12345, fun () -> ...) This should be pretty easy to implement; do you like it? |
On deeper reflection, there is a complication with a global, mutable, session approach: A RemoteSymbolicExpression is not a SymbolicExpression - it's a handle to a SymbolicExpression in the remote session. To make this work the functions generated for the R type would need to handle both types and perform appropriately. Further... calling code would have to deal with them, too; the return type of all R functions generated by the type provider would have to be a discriminated union, something like: type RProviderExpression =
| Local of SymbolicExpression
| Remote of RemoteSymbolicExpression Of course, that's a non-starter as it would break all current code. Maybe we could establish a ... generic kind of RemoteR type that uses local discovery and represents a remote session. open RProvider.``base``
...
// RR is a type provided similarly to R and must be runtime-configured to
// use a remote session. Discovery is done locally.
RR.UseRemoteSession("localhost", 12345)
RR.do_something_in_remote_session(some_arg, another_arg) I think that my suggestion to have an type RR = RemoteR<"localhost", 12345, false> |
My thoughts:
|
I was concerned about the On the remote symbolic expressions being passed around - I wasn't really addressing that. I agree, though, you should be able to pass them around between remote sessions and I need to check if that is handled correctly already (it may not be). The real concern I have is overloading the let dowork(df) =
use session = RemoteR("localhost", 12345)
R.as_data_frame(R.cor(df)).Value The let dowork(df) =
use session = RemoteR("localhost", 12345)
RR.as_data_frame(RR.cor(df)).Value This keeps the local |
RemoteSession provides a way to create a connection to a remote R process via the svSocket package for R. Some functions in RInterop are generalized to allow as much reuse as possible for functions that perform the same behavior whether local or remote.
The RemoteR type provider provides a way to import and export data between F# and R sessions, as well as make remote calls to a running R session.
Enable launch of RGui from fsi. Ensure that svSocket is installed and launch the socket server.
When the R svSocket server isn't running produce a better error message. Also, set a default timeout so that the type provider doesn't hang waiting for the R svSocket server if it isn't running.
The addition of the RData paramterized type caused problems resolving the RemoteR type. To fix this, the RemoteR type was moved to the RProvider.Remote namespace. There appears to be a limitation in the F# type provider facility restricting the number of parameterized type providers to one per namespace.
The new RR type provider works much the same as the R type provider, but requires that there be an active session in the current thread. To use, you create an RRSession. For example: use session = RRSession("localhost", 8888) let remoteSymbolicHandle = RR.c(1,2,3)
This is superseded by #115 . |
Add support for interacting with running remote R sessions, such as RGui or RStudio. Requires and uses the R svSocket package to make requests and marshal data to/from the remote R session. Also, provides a remote R type provider.
The remote R session type provider support requires a different syntax than the original R type provider due to current limitations in the FSharp compiler. A future version of the FSharp compiler should support type extensions generated by type providers; this expected improvement in the compiler will enable the remote R type provider to provide a syntax and development experience much closer to the original local R session type provider.