Lee,
With the new input/output stream methods in
TerminalEmulation,
one has to make the following call:
session.bindInputStream(emulation.getTerminalInputStream());
This method creates an IOStreamConnector object. That,
in turn creates an "IOStream Connector" thread.
I am calling session.close(). But that is not removing
the thread.
I have placed log messages and new
Throwable().printStackTrace calls right after the while
loop in the IOStreamConnectorThread.run method. But
they are never logged.
I have a background thread that prints the thread name,
Threadgroup name, and isAlive() status for every thread
in the jvm. The number of "IOStream connector" threads
keeps increasing and all return an isAlive status of true.
Also, although the methods are easier to understand,
the ssh connection requires an extra thread as compared
to the earlier version of TerminalEmulation.
The older version of TerminalEmulation class was better
for me. With that I did not have to to a
bindInputStream call on the session object.
For my application, this is very significant. Since i
am attempting connect concurrently to 300-500 servers.
I need to bring that number to 1000.
-Moiz
Logged In: YES
user_id=600074
I will post this to the users list as it may be useful to others
..
The problem is caused by the IOSteamConnector thread
being stuck in a read operation on the TerminalInputStream.
When the channel is closed, the IOStreamConnector is also
closed, but this only has the effect of setting it to a closed
state, the thread is still blocking on the read.
I fixed this by adding some code to the terminal emulation
reset method, in which I simply write out a zero value byte to
the various output streams of the terminal emulation. Once
the session has been closed, simply call emulation.reset()
and this will stop the thread.
You can then also reuse the emulation instance.
I am using a custom class for this, DynamicBuffer which
exposes both the streams, I have found it much more efficient
that piped streams, in fact the performance of SSHTerm was
so bad with piped streams and that was one of my main
considerations.
Perhaps we could look at having some sort of provider
interface for the streams, so that in construction you can
supply your own?
I've not really thought too much about this but I think
something like the following should allow you to remove the
need to bind to the session.
public interface TerminalInputProvider {
public InputStream getInputStream();
public OutputStream getOutputStream();
public void reset();
}
Then if you combine the creation of the session with the
emulation you could do something like:
TerminalEmulation emulation = new TerminalEmulation(....,
new TerminalInputProvider() {
public InputStream getInputStream() {
// Return null as you are never going to call this methd
return null;
}
public void getOutputStream() {
// Just return the session output stream
return session.getOutputStream();
}
public void reset() {
// Do something to reset
}
});