Skip to content

Conversation

@osa1
Copy link
Owner

@osa1 osa1 commented Sep 29, 2019

This PR basically rewrites the whole app except the TUI parts. The main motivation is to make the code easier to work with.

Main changes are:

  • The code is now split into a few crates, with few inter-dependencies. Dependencies between the new crates look like this:

    tiny
    ├── libtiny_client
    │   ├── libtiny_logger
    │   │   └── libtiny_ui
    │   └── libtiny_wire
    ├── libtiny_logger
    ├── libtiny_tui
    │   └── libtiny_ui
    ├── libtiny_ui
    └── libtiny_wire
    
  • The main crate (tiny, which previously implemented pretty much the whole program) now does a few things:

    • Updates the UI on events from a client (libtiny_client). This is implemented in conn.rs in 510 lines.
    • Updates IRC clients on events from the UI (currently libtiny_tui). This is implemented in ui.rs in 159 lines.
    • Implements commands like /connect, /away, /join etc. (UI-related commands are now handled in the UI libraries, e.g. libtiny_tui)

    Other than these it just glues the libraries together: initializes TUI, clients, logger etc.

  • libtiny_wire implements parsing and generating IRC messages. Only difference from the previous wire module is QUIT and NICK messages now have a field for channels of the user who quit or changed their nick. libtiny_client updates these fields, to be used by the main crate.

  • libtiny_client implements the IRC driver. It handles reconnections, nick selection, authentication, ping/pongs, sending messages etc. Users interact with a client using a the Client methods and receives IRC events from a tokio mpsc channel.

    Note that once created, a client is only destroyed when the user wants to close the connection to the server -- that is, clients are not destroyed on connection errors.

    A client now maintains a list of nicks for every channel joined, and updates chans fields of QUIT and NICK messages before sending them to the user, so that UIs or the logger doesn't have to maintain a list of channels a user is in.

  • libtiny_ui defines a trait for UIs and a few utilities for combining two UIs (see below).

    (This will be used for a GUI in the future, see the placeholder libtiny_gui crate)

  • libtiny_tui is the good old TUI implementation, which now implements the UI trait from libtiny_ui. The top-level is refactored to support use with tokio -- most notably it implements Clone and methods now require &self (instead of &mut self as before).

    Similar to Client (libtiny_client), TUI events are returned to the user using a mpsc channel.

    Other than that the code is the same as before.

  • libtiny_logger implements logging. Logger is implemented as a UI, so in the use site we don't actually do any logging, we just combine the main UI (the TUI) with a logger (if logging is enabled by the user), and then rest of the code just updates the UI as usual. This is quite convenient in the use sites.

For debug logging we now use env_logger. By default debug logging is disabled. When enabled logging is done to stderr. Because some of the dependencies (e.g. tokio) also use the standard log crate it's a good idea to limit the logging scope, using something like:

RUST_BACKTRACE=1 RUST_LOG="libtiny=debug,tiny=debug" tiny 2>stderr

Breaking changes

The only breaking change is that the /reload command is currently disabled. This is because the command is somewhat special in that it requires parsing the config file in the UI, and I couldn't find a good way to implement this yet.

Other than that this is pretty much just refactoring. Only user-facing change is the new logger (it's a good idea to remove the old logs directory before starting using new tiny, but it's not necessary, logging will still work).

Trivia

  • Code size: before 7498 loc, after 7762 loc (+264 lines, +3.5%)
  • Debug executable size: before 24M, after 54M (+30M, +125%)
  • Release executable size: before 2.3M after 3.9M (+1.6M, +69%)
  • Debug build time after git clean -xfd: before 17.90s, after 26.96s (+9.06s, +50%)
  • Release build time after git clean -xfd: before 39s, after 1m11s (+32s, +82%)
  • Number of transitive dependencies (using cargo metadata --format-version=1): before 118, after 168 (+50, +42%)

Fixes #100
Fixes #94
Fixes #3
Fixes #56
Fixes #132

@osa1
Copy link
Owner Author

osa1 commented Sep 29, 2019

There are a few remaining issues in libtiny_client before merging this, see #136 .

@osa1 osa1 merged commit 969e9c7 into master Sep 29, 2019
osa1 added a commit that referenced this pull request Oct 3, 2019
Before #138 a SIGWINCH would cause mio's poll() to fail, and on every
error we'd check GOT_SIGWINCH variable (which is set on SIGWINCH).

After switching to tokio this stopped working (see #142 for more
details). SIGWINCH handling is now done via tokio_net's signal handling
facilities, in TUI instead of term_input.

Fixes #142
@tesuji
Copy link

tesuji commented Oct 30, 2019

This helps rust-lang/rust#65819

[INFO] [stderr] error[E0271]: type mismatch resolving `<[closure@src/tui/msg_area/line.rs:236:68: 236:74] as std::ops::FnOnce<(&tui::msg_area::line::Seg,)>>::Output == &tui::msg_area::line::Seg`
[INFO] [stderr]    --> src/tui/msg_area/line.rs:236:37
[INFO] [stderr]     |
[INFO] [stderr] 236 |         for seg in self.segs.iter().chain(last_seg.into_iter().map(|s| *s)) {
[INFO] [stderr]     |                                     ^^^^^ expected struct `tui::msg_area::line::Seg`, found reference
[INFO] [stderr]     |
[INFO] [stderr]     = note: expected type `tui::msg_area::line::Seg`
[INFO] [stderr]                found type `&tui::msg_area::line::Seg`
[INFO] [stderr]     = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Map<std::array::IntoIter<&tui::msg_area::line::Seg, 1usize>, [closure@src/tui/msg_area/line.rs:236:68: 236:74]>`
[INFO] [stderr] 

@osa1 osa1 deleted the async_refactor branch October 12, 2020 07:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants