migueldeicaza / SwiftTermApp

MIT License
305 stars 29 forks source link

Actors async #98

Closed migueldeicaza closed 2 years ago

migueldeicaza commented 2 years ago

Move to use actors and async/await instead of manually managing state with queues, and avoiding busy loops.

First, this set of changes uses both actors to simplify the requirements to only call libssh2 methods on a session from the same thread. Previously this was enforced by sending all operations to an sshQueue, now all code that needs to be bound to a single thread are instead pushed to an actor, in this case SessionActor. In libssh2, multi-threading can happen only for different sessions, and any objects that rely on it.

The new SessionActor has thus all the operations on an libssh session, the channels (that are tied to it), and SFTP (tied to it as well).

Second, previously, when libssh2 was unable to complete a request, it would return EAGAIN, and my code would busy loop until enough data was received or sent. This is problematic, as this would just spin the code waiting for a potentially slow network connection. Not only was this burning GPU, in addition, it would hoard the sshQueue, so if a libssh2 call had to be retried, no further operations could be processed until this was done. While this was acceptable for most uses of a terminal emulator, it would prevent me from reusing libssh for transferring files and not clog the system.

Actors had the nice side effect of dealing with problems that I previously had to debug with assertions on specific queues, and during the development, I did not experience deadlocks (which were way too common to introduce with my manual queue management) or memory corruption issues.