-
Notifications
You must be signed in to change notification settings - Fork 17
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
Installing on Windows #279
Comments
Not yet. It's a known limitation that the library does not work on windows On Tue, May 19, 2015, 8:28 AM ncreep notifications@github.com wrote:
|
I would be interested in taking a stab at this issue, but I have no experience with such things. Maybe with some initial guidance I can get into it. Is there some simple, self-contained problem that you can point me to to get me started? |
My guess is that the best place to start is to make the Pinging @mgsloan and @urbanslug on this, perhaps we can use this issue as the base-of-operations for Windows support. |
Thanks for the pointer, I'll be looking into it soon. |
@urbanslug I'm definitely okay with it. As I mentioned earlier, I really don't have any experience with these things, so any help/guidance is most welcome. In the meantime, a naive swapping of |
Also, I see that the Darcs repository has an |
@urbanslug If @ncreep is taking a crack at it, it's worth spending some time to make sure it will address the use cases the GSoC has. But I'd focus on the simpler requirements for now (like automatic data file discovery). @ncreep Unfortunately, I doubt that |
Yes feel free to add windows support, it'd be great to have! We would indeed need an alternative to named pipes. Looks like windows has such a thing, but they aren't in the filesystem, and you need to use a special API for IO for them. This seems ugly and I'm not sure if there are haskell bindings for it. Another possibility is to use a localhost network connection. I don't think we'd want to do this when we posix pipes are available, though, as it'd be a bit less efficient. This approach has the advantage of also making it easier to support non-posix / non-windows OSes, down the road. |
@ncreep Email me at the email address in my profile so that I may contact you and discuss this further. |
@ncreep Nope, that's my branch for the School of Haskell, which will be merged in when it's ready. It adds support for running code with a unix pty. So, it actually makes it less compatible with non-unix platforms. I wanted this because I'm using term.js as a terminal emulator in the browser. This it lets you use things like ghci, ncurses based apps, etc. I imagine this feature would probably be disabled for windows, unless there's a way to do something like forkpty in windows (note: this isn't how the feature is implemented, but it's essentially the same thing. My implementation uses forkProcess |
Okay, thanks for the detailed response. So I'm guessing that using a localhost network connection as you suggested before is the most reasonable direction to pursue. |
So I started (naively) playing around with the sockets idea. My aim was to just imitate whatever was being done with pipes (and figuring out what it is that they are doing along the way). Going in this direction, it seems like I'd have to use port numbers in the same way that the pipes code uses temporary files. This doesn't seem like a good idea, since I can imagine that there can be many clients connecting to one server, and having a port for each one seems excessive. A more complicated direction would be to use a single port (on the server) and then let every client connect with some unique id. The id would be used to dispatch the messages from the server to the various clients. This sounds like overkill compared to the simplicity of named pipes. Am I missing something very simple, or is it going to be a full-blown inter-process communication thing? |
There's only ever one ide-backend talking to one ide-backend-server. But even if that wasn't the case, you have tens of thousands of port numbers; using a few extra doesn't seem like a big deal. |
Doesn't the |
I'm not sure of the details there, it would be nice if @edsko could clarify. I don't believe it is intended to support multiple connections to a single server, though. |
Yes and no. When the server starts there is a single conversation to that server. Whenever the client requests to run a snippet, the server starts an auxiliary "concurrent" conversation (which uses its own set of named pipes), sends the names of those pipes back to the client, and then forks off an auxiliary server which will be running the snippet. The main server keeps communicating on the original conversation, and the auxiliary server, which runs only for the duration of the snippet, communicates over the new concurrent conversation. |
Okay, so if we are using potentially more than one port, the code needs to figure out how to find an available port. Is there anything more elegant than trying to bind a port and if it throws an exception retry with another port number? |
Binding to port 0 seems to work on Windows: {-# LANGUAGE OverloadedStrings #-}
import Data.Streaming.Network
import Network.Socket
main :: IO ()
main = bindPortTCP 0 "*" >>= socketPort >>= print |
Thanks, didn't know that. |
Yet another question (sorry for asking so many questions...): while browsing the code I stumbled upon the |
Hi! No worries on the questions, sorry for the delay in answering. |
Thanks, no problem about the delay, I'm currently away from a development environment anyway. |
That's probably me not really understanding the code flow (and how pipes work), but why do the |
I don't follow. If by anonymous pipes you mean file descriptors, how would the server share file descriptors with the client? They are only inherited at process startup. Sure, I could send the number of a file descriptor to a process, but that doesn't mean that number would refer to a valid file descriptor in that process. |
Ah, I see, that makes perfect sense, thanks! I didn't realize that's how file descriptors work. |
Okay, thanks. I somehow thought that there's more flexibility in passing file descriptors when the processes have a child/parent relationship (after the fork). |
So I made some progress: managed to rewrite the communication parts in In order to test the changes, I tried to compile both projects and found further complicating issues:
As a result, I was able to compile and run Going further, is it possible for the sockets solution to completely replace named pipes? The advantages are:
Regarding the efficiency issue, we could use Also, any pointers on how to resolve the above-mentioned would be most appreciated. |
Due to historical reasons, these errors are reported by I will need to dig into the code more than my tired brain can right now to determine exactly how server-side exceptions are handled. I thought they were written to a log file and read by the client, but I can't find the relevant code right now. |
Also, I've attempted to make the stream error messages a bit less obtuse: 2a2ccee |
Sorry for taking so long to reply, I was away from a proper development environment for a while. The migration to
Anyways, the actual result of running |
Seems like maybe there's an issue with cabal flags and ghci support. Stack's support for ghci is still quite WIP.. In the meantime maybe use
Yeah, this isn't so ideal. There's a relevant discussion here: commercialhaskell/stack#426 I just open up |
... and I thought that
Running the tests in the
Holding my fingers crossed that this might resolve some issues on my end. |
Another peculiar thing is that running the tests with |
Certainly ought to remedy all your cabal-install woes! The GHCI feature is just not a priority, and Chris has been busy. Fixes welcome, of course! Some of these fixes will also be helpful for the
Yeah, sorry it got into this state. I didn't realize travis wasn't actually running the tests.
My fixes have pretty much all been to the test suite itself, making it automatically run well under For me the test-suite passes for GHC 7.10.2. Travis is showing failures for GHC 7.10.1 / 7.8.4, but I haven't quite gotten around to addressing those. Once nice thing is that testing with 7.8 is now as easy as |
My nitpick with
Sadly, the tests on Windows still run the same. Thanks for the @urbanslug and whomever wants to try and run the Having done that, all tests pass till the |
I've managed to track down the reason why the The exception itself is thrown in The question now is, how come |
I think I now have the So what do we do with it, just swallow the exception and pretend that it returned an empty string? Or is there a legitimate scenario where the exception from the offending line should be propagated as is? |
As I mentioned earlier passing It seems that running any single test without session reuse on WIndows gets it stuck. Which is not the case when running the sockets implementation on Linux. |
I take my statement from above back, not every test fails when not reusing sessions, it's the tests that try to run statements on the server, which at the moment fails with an exception. Given how much throwing an exception from the server complicates things, I think that I'll try implementing an alternative solution where instead of throwing an exception the server will send some erroneous value back to the client, and let the client handle the rest. But in any case, the fact that exceptions mess things up so much should probably be addressed somehow. |
The test-suite should pass reliably now - travis passes! https://travis-ci.org/fpco/ide-backend While this is a bit hacky, one thing to note is that now I agree that the error handling for the server should be revisited. It's unfortunate how so many errors manifest as "demandInput: ..." errors on the client. |
Congrats on getting travis to work. I've implemented what I described above, so now the client gets to handle the fact that command running is not supported on Windows. With this in place But Also, there's some inconsistency with file path separators, so sometimes paths like |
I stumbled upon something really weird, I'm trying to get the "Make sure we can terminate the IDE session when exe is running" to work. It seems that the test ignores some side effects, namely the forceCancel side effect (and also print commands around that line). Though the executable is created and run. Any suggestions as to what could've gone wrong? |
I've rebased and pushed the windows branch to the fpco repo, and here's the travis results: https://travis-ci.org/fpco/ide-backend/builds/75006301 . Note that you can also add your repo to travis. Looks like there's just one test failure, good work!
I'm not sure what's going on here, but without digging in to the code, my guess is that killing the forked process is causing the stream to close. Maybe that
Is this with windows or on linux? Does your branch of ide-backend function on windows? |
Thanks. Nice to see that there are less errors than on my Linux VM. Strangely, the error that I get for that test is:
It seems that socket handles are not nice when they're forcibly closed. I'll have a bit of hard time fixing this test, since it's skipped on Windows anyways (because of
That's already outdated, I've managed to fix the Related to the above, generally, it seems that when some test fails unexpectedly with an exception, it can potentially freeze the rest of |
How's this going? I was going to give getting stack-ide-sublime working on Windows a whirl sometime soon — is your branch mostly functional?? Thanks so much for tackling this!! : ) |
@lukexi I think that the Also, as it stands, there are features of If you want to be doing anything off my branch, notice that I abuse it occasionally, e.g. resetting and rebasing. |
@mgsloan I've finally managed to tackle the #220: Calling forceCancel ... bug.
Anyhow, at the moment, it seems that the build is working. Though I do occasionally have problems with the script for 7.8, which randomly fails before actually running anything or gets stuck typically around the |
Given the above, I would like to open up for consideration the merging of my fork into Although there are still quite a few issues to iron out when running on Windows (apart from the completely disabled snippet running functionality), I think that most of the functionality is there. Regarding Linux, there's still the question of whether it's okay to use regular sockets, or should they be replaced with Unix domain sockets. Is there anyway to benchmark the performance hit (if any) from using sockets as compared to the original pipes implementation? |
@ncreep Cool, looks good to me, awesome work! I'm using it locally with stack-ide, and so far it's working fine. I'm in favor of merging soon, how about opening a PR from your branch to master? Ideally we'd use unix domain sockets, but that can be a separate issue, and shouldn't block merging this in. |
PR opened. Might look into the Unix sockets thing soon. |
I'm not sure how all these pieces fit together, so I'm not sure this has any relevance to ide-backend on Windows. With that disclaimer out of the way, I tried to run "stack ide" on Windows using the "windows" branch of ide-backend. In brief, I couldn't get it to work. In not so brief, I tried to run "stack ide" within a stack project. It generated the following output:
I ran a trace during this process and determined that
At some point, this stack-ide process attempted to access a file with path |
@dpratt71 I think that this issue on |
I'm going to close this out, since it's implemented. Thanks again, @ncreep ! |
Hi,
I tried installing
ide-backend
on Windows, but the dependency on theunix
package fails the whole process (even when using Cygwin).So, are there any workarounds for getting
ide-backend
to work on Windows?Thanks.
The text was updated successfully, but these errors were encountered: