Does anyone else find that sclang fails to release its port when rebooting the interpreter?
This happens so often to me that I ended up putting some logic into my startup file to check NetAddr.langPort and, if different from 57120, get PIDs from fuser 57120/udp and kill those processes, and then quit the language to be free and clear to reboot again.
I’m not clear on the ins and outs of OS port management. I’d have assumed that sclang’s exit would release the port so that it would be available for the next sclang instance. In practice, this seems not to be happening.
Does it happen when running the process again soon after killing it, or is there no relation? vscode/linux specific?
(The command fuser in Linux makes it possible to just kill any process listening to a given port, which might be simpler workaround since it checks the PID and kills the process with one command)
What do you mean exactly? Do you get an error message? If yes, please post it.
Generally, the OS releases all open file and socket handles when a program exits, so even if sclang did not properly release its resources, the OS would do anyway.
A UDP port is typically released immediately after closing the socket. There is no need for the OS to keep it around.
Side note: TCP ports are not immediately released because of CLOSE_WAIT and TIME_WAIT states (windows - What are CLOSE_WAIT and TIME_WAIT states? - Super User). That is why Pd sets the SO_REUSEADDR flag on TCP sockets which allows to bind to an already bound socket. This makes sure that you can close and immediately reopen a patch and still use the same TCP port.
I’ve observed this behavior when rebooting the interpreter from within sc-ide (but not when restarting sclang in vscode), and when sclang crashes and I subsequently boot the interpreter.
I don’t recall seeing this in Windows, but I seldom use Windows or Mac so I can’t say for sure that it wouldn’t happen.
There’s no error. Sclang just cheerfully occupies 57121 instead. But this messes up my Open Stage Control interface, so I added the logic to detect the situation automatically.
This, I don’t recall. I wonder now if it’s SC-IDE. Maybe the other process is supposed to release it, but doesn’t do it fast enough.
You know, I don’t remember seeing this on my old computer, which had a not very speedy HDD instead of the lightning fast SSD that I have now (and CPU speed also matters). Maybe I never saw it before because library compilation took a full second, long enough for the port to get dropped outside of sclang. On my current system, compilation is a good 10 times faster, so sclang may be trying to grab the port sooner than it’s available.
User impact is mainly that I need to reboot the interpreter twice – it’s minor, just a point of curiosity.
I’ve noticed this switching between 57120 and 57121 as well, but only when using Open Stage Control. That doesn’t mean it wasn’t/isn’t happening other times, but I’ve never really been able to consistently reproduce it or notice any patterns regarding when it happens. I’m on MacOS…could it be something to do with o-s-c overstaying its welcome on the port perhaps?
After a quick look at the code, SC-IDE seems to properly wait until the old sclang process has finished before starting the new one.
It could also be that the OS intentionally keeps the UDP port open for a while, e.g. to prevent inbound messages still in transit to be received by the wrong application. Will do some tests later.
yea, terminating a process by itself will not terminate its child processes in linux. you need to be explicit. To signal all processes within a specific process group, you need to send the signal to the process group. parent’s PID requires a minus symbol before the parent’s process ID (if you use a simple kill command, for example).
BTW, SC-IDE does not quit sclang by sending a signal (which wouldn’t work on Windows), it rather asks it to execute the code 0.exit;, then waits until the process has finished (or terminates it after a certain timeout).
Good to know you’re close to solve it. I was not saying that’s how sclang would do it, I was just giving an example how child process survive by default in linux, the reason one needs a special syntax when using common system tools…