Community
Participate
Working Groups
Client code often needs to perform a command on the remote side and wait for its completion. Either wait until the shell is done, or until the command is done. We should have new API for this: I'm suggesting IHostShell#waitFor(long timeout) int IHostShell#writeToShellAndWait(String command, long timeout) IRemoteCommandShell#waitFor(long timeout) int IServiceCommandShell#writeToShellAndWait(String command, long timeout) If the corresponding code is implemented in the abstract base classes AbstractHostShell, RemoteCommandShell and ServiceCommandShell, this change could be implemented in a backward compatible manner. For a start, waitFor() could be implemented like in HostShellProcessAdapter#waitFor(); in the future, it could be optimized by listening to the event when the IHostShell is terminated. writeToShellAndWait(String command, long timeout) could work like this: 1.) Add an OutputListener to the IHostShell that will run in a separate thread and reacts to a certain text pattern, e.g. '-->RSE:done:<--' When it reads this pattern, it wakes up your main thread: synchronized (fDoneSemaphore) { fDoneSemaphore.setDone(); fDoneSemaphore.notifyAll(); } 2.) In your main thread, you do writeToShell(command + ssConfig.getCommandSeparator() + "echo '-->RSE:done:<--'"); synchronized (fDoneSemaphore) { while (!fDoneSemaphore.isDone()) { fDoneSemaphore.wait(); } } In fact, writeToShellAndWait() could even return the exit value of the remotely executed command.
Dave's - can you comment on this idea?
We have something like that in RemoteCommandShellOperation, which is a wrapper to the basic shell stuff. I works via an echo tag as suggested here. I wonder whether this functionality should be left at a layer above services or whether we should do it at the service layer. I suppose doing it at the service layer would allow for protocol-specific optimizations. What do you think?
That's very interesting! In fact, RemoteCommandShellOperation seems to be doing what we need, though it appears to be more complex than required -- a simple "writeToShellAndWait()" appears to be easier to use. Unfortunately, currently there is no sample usage of RemoteCommandShellOperation anywhere in openRSE. I think that when the ssh processes contribution is accepted by EMO Legal and checked in, we should re-write it to use RemoteCommandShellOperation. Having a sample usage of this will allow us to better understand what it does and decide whether it should eventually be at service or subsystem layer.
One disadvantage of RemoteCommandShellOperation in terms of performance, seems to be that it goes all way through the (global) resource change mechanism. I guess that in many cases, only a single consumer of an IHostShell will be interested in it, so some "peer to peer" communications between the shell and the consumer would be more effective.
We also have a similar utility called SimpleCommandOperation. This wrapper is nice in that it is fairly simple, however it doesn't do the command tagging stuff.
Both SimpleCommandShellOperation and RemoteCommandShellOperation seem to be good tools. However, they are currently nowhere used in OpenRSE. We should provide same example code that uses these classes. Allso, according to comment #4, a new API for IHostShell might make sense in order to allow efficient running of commands on the Service layer without involving the whole ResourceChange mechanism.
I won't have time to look at this this release.