SwiftTermApp Split Session
Branch: extract-session-from-terminal


Currently the SshTerminalView contains the code for setting up the session, as well as some other goodies.   The idea is to extract the session components into Session, so that the entire connection setup can be used without the SshTerminalView at all. 

This will be useful in a number of scenarios:
  • Not requiring a terminal for status display
  • Not requiring a terminal to setup tunnels
  • Being able to launch multiple terminals over the same session (lots of hacks can be done today to achieve this, I don't think it is worth it).
  • Incremental work to make it so that we could have multiple SshTerminalViews backed by the same terminal, which would solve a spectrum of SwiftUI issues.

Pending tasks
  • Terminal count: currently uses a computed property, and this is not a “published” value, so the display does not update, need an “onAppear” to update this
  • Bug, creating three of the sessions sometimes hangs one of them, in “ssh authenticated”
  • Bug, it now sometimes will refuse to connect to a host, and show protocol errors after the connection is closed.
  • Repro: connect to Pi, disconnect from Pi, try to reconnect to Pi:
  • Connection error Failed to request pseudo-terminal on the remote host, 
  • Detail: LIBSSH2_ERROR_PROTO
  • Bug: the raspberry pi shows the prompt twice?
  • RESOLUTION: all of the above and below were the strengtheining patch that is caused by the description below, I should still drop the SessionDelegate idiom, and instead make it a “Call this method when the session is established, and when there is an error”
  • BAD DESIGN: the delegate for the session does not work this way!   And the way in which I poke a nil and then a new instance is bad!
  • Because the session is shared across many different TerminalViews, but passing a delegate to a child session is wrong.
  • Instead we need to pass the “Call this when you lgoin” and “Call this when you fail to login” which is what we actually want, or maybe it should be a combine published object that we subscribe to.
  • Session should be created with a UIViewController, to avoid the callback being invoked on a non-UI thread, also would be resilient.
  • TODO: currently the session is aware that the terminal supports tmux, which is fine for now to indicate “reconnect me”, but also we need a proper contract to reconnect with the terminal(s) now - what if we had many terminals?  They all need to be reconnected.
  • Once the merging takes place, “Sessions” really needs to be renamed “Terminals”, and likely need to show Sessions somewhere.

Future cleanups, not related to the split:
  • The code that relies on Connections.lookupActive(host: host) is bad, because it relies on the Host, but there could be more than one connection open, so this is generally a poor proxy.
  • Introduce a concept of transient channels, vs permanent ones.   
  • Transient are those that we can kill at will, while permanent keep the session alive for as long as these are active (terminals are permanent, load averages are transient)
  • Currently this exists, but is not explicit: terminals count is what drives killing the session, not open channels.
  • Should really “pop” to the root controller after a login fails, or a connection is closed.

TODO/test:
  • test: that tmux restoration still works
  • test: checkHostIntegrity works
  • test: showHostKeyMismatch works
  • test: authenticate errors remove the session from the list of active sessions
  • test: connectionError during operation
  • test: that slow connections will log the messages.
  • TODO: checkHostIntegrity kills session on closing
  • TODO: showHostKeyMismatch kills session on closing
  • TODO: connectionError kills the session on closing
  • test: that creating a new connection reuses the session
  • TODO: ensure we still close everything if we control-d a terminal
  • Dialog box shows up