ericmandel / js9

astronomical image display everywhere
https://js9.si.edu
Other
124 stars 51 forks source link

can js9Helper be made to print the port it's binding to? #38

Closed o-smirnov closed 6 years ago

o-smirnov commented 6 years ago

Under the Jupyter scenario, I'm going to need to run js9Helper.js on a per-user basis. This means somehow allocating a unique port for it to listen on. I can set helperPort to 0 which, presumably, causes it to pick a random unused port, but then I have no way of finding out what port was picked. Could you please add a print statement with the port number so that I can parse this out?

ericmandel commented 6 years ago

Why do you have to run the helper on a per-user basis? The JS9 helper handles multiple users. Everyone initially contacts the helper via the same port (def: 2718), but then makes their own private connection for the actual messaging.

o-smirnov commented 6 years ago

Well, I'm trying to set up an install-free environment for connecting to remote servers that don't necessarily have a webserver, or a central install of JS9...so the user ssh's in, and a script launches a Jupyter notebook, a SimpleHTTPServer (to work around the current Tornado problems), and a helper. I can let the former two pick unused ports and parse it out from their output, but I can't currently have the helper pick a port.

ericmandel commented 6 years ago

OK, I added code to the helper to output its listening parameters, e.g.:

helper: 0.0.0.0 2718  [2018-7-4 12:50:00]

I'll let you know when its updated into GitHub, I'm still trying to ensure that every Jupyter-related change is stable.

o-smirnov commented 6 years ago

OK, that didn't really help -- if I give it port 0, it reports back port 0. What I really want is to force it to select an unused port at random. But googling around, it doesn't look to be that trivial, at least with socket.io:

https://stackoverflow.com/questions/44896156/use-an-ephemeral-port-with-socket-io-server

Unless you're willing to add this library: https://github.com/indexzero/node-portfinder

Otherwise I can kludge around it.

ericmandel commented 6 years ago

[I guess I still don't understand why you can't share a single instance of the js9 helper between users. In the js9Electron (Desktop) code, we check for the existence of a helper and if it does not exist, we start one up. Otherwise we use the running helper. This allows Desktop and browser-based JS9 to run simultaneously. Can you please explain more about this?]

With port-finder, it's unclear how to tell the client which port was chosen. This currently happens by means of the js9prefs.js/js9Prefs.json files, since the client must know the port in order to start the initial connection. I think we will end up with a chicken and egg problem if the server chooses the port without a way to tell the prospective clients .... except ...

... well ... it might be that your application can run port-finder outside the helper, passing the port to the helper on the command line, and also manually setting JS9.globalOpts.helperPort (and removing this variable from prefs entirely) before loading js9.js.

o-smirnov commented 6 years ago

[I guess I still don't understand why you can't share a single instance of the js9 helper between users.

I'm trying to make a zero-admin, zero-install solution. All the user should need is an ssh connection. But then that user does not have the privileges to start a shared js9helper...

With port-finder, it's unclear how to tell the client which port was chosen.

Ah, but that's why I asked you to have js9helper print the chosen port. My startup script could then parse it out, and pass it to the notebook, and the notebook can set it in JS9Prefs.globalOpts (after loading js9prefs.js, but before starting the rest of JS9...)

(And yes, I realize it sounds fiddly, but I've had to solve exactly the same problem with Jupyter itself to begin with. It also chooses a random port -- many users can be running many Jupyters, so it can't use a fixed port -- which I then need to tunnel to via ssh, etc. etc.)

But indeed I can also choose a port in the startup script, and pass it to the helper, now that you have the command-line JSON feature.

ericmandel commented 6 years ago

But then that user does not have the privileges to start a shared js9helper...

Ah ... but I don't know that it matters which user starts the shared helper, so long as the PATH is set properly. well ... the top-level directory in which all users' working directories reside would have to be writable by that user, with enough space for all ... perhaps that is the bottleneck.

That said, I think your best bet is to choose a port and communicate that info to helper and client ...

o-smirnov commented 6 years ago

well ... the top-level directory in which all users' working directories reside would have to be writable by that user, with enough space for all

...and r/x access to the other users' directories and files would also be needed, which is not guaranteed at all. Plus, figuring out paths would be a whole new mess. If Alice starts a notebook (and a helper) under ~alice/foo, and Bob runs his notebook under ~bob/bar, how would Alice's helper even know where to look for Bob's images -- unless Bob's client asks for images by their absolute server-side paths -- which it doesn't even know about, since to Bob's client, ~bob/bar is /... No, I'd much rather go the per-user helper route...

ericmandel commented 6 years ago

and r/x access to the other users' directories and files would also be needed,

Ah, that's all that needs to be said.

ericmandel commented 6 years ago

The ability to specify a port on the command line has been implemented and is in use, so I believe this issue is solved.