Neon DevZen

Selling points (10-15 mins, maybe 18 if discussion rises)

  • Formal guarantees: not only the powerful type system with borrowck, but also pluggable formal verification!
    • MUST: Rodionov: Newtypes (talk about ZId/ZTimelineId)
    • MUST: Rodionov: Error handling: Result and Option versus C-style -1, mention panics, helps to pay attention to various error conditions (this fsync failed etc)
    • MUST: Ivanov: Borrow checker: interating over a vector and trying to extend it
    • MUST: Rust basically requies that your code is completely UB-free / #![forbid(unsafe_code)] cargo-fuzz (llvm libFuzzer)
    • MUST: Rodionov: Testing frameworks: the built-in is good enough, but there's also proptest / QuickCheck (courtesy of Haskell)
    • Paper: Rodionov: Using Lightweight Formal Methods to Validate a Key-Value Storage Node in Amazon S3 (Tokio maintainer works for amazon) TLDR property based testing, failure injection, model checking (loom), other tools
  • Rust is a healthy community (kind and smart people, no stale problems)
  • Everybody can contribute: rust-analyzer (mention Kirill), documentation, various workgroups (async/graphics/stdlib/borrowck/types)
  • Rodionov: Rust ecosystem is a young adult: crates.io works like a charm (think CMake/Autotools + vendoring)
  • Rodionov: Rust is big: we have a foundation and major players, i.e. Amazon, Microsoft, Google Fuchsia has rust code, yada-yada
  • Rust is popular among new database/data management projects
    • quickwit Quickwit is the next-gen search & analytics engine built for logs. It is a highly reliable & cost-efficient alternative to Elasticsearch.
    • databend A Modern Cloud Data Warehouse with the Elasticity and Performance both on Object Storage
    • materialize Materialize is a streaming database for real-time applications.
  • Rodionov: Some people say that nightly is a must, but we (Neon) use stable and have everything we need

Async woes/rant (20-40 mins, the more the better)

  • Introduction (5 min)

    • std::future::Future and poll and waker, stackless coroutines
    • async fn === fn -> impl Future
    • Uses unstable generators feature under the hood (thus backtraces are bad, but there's tokio-tracing)
    • GOTCHA: futures may be self-referential, what about rust's guarantees? Talk about Pin
      Pin and suffering
    • Rodionov: Function colors: red vs blue, dual APIs: poll based api vs async fn (AsyncWrite: poll_write, AsyncWriteExt async fn write (not really fn write() -> Write + impl Future for Write))
  • Async: async methods in traits (5 min)

    • Give definition
    • BRIEF: Missing feature: GATs (mostly for lifetimes) TODO: link to issue
    • BRIEF: Missing feature: TAITs (for anonymous futures) TODO: link to issue
    • Rodionov: MUST: Temp solution: async_trait by dtolnay. Minuses:
      • boxed futures per call
      • proc macro: comptime, IDE experience
      • various problems with lifetimes
  • Async: cancellation (5-8 min)

    • Give definition
    • How do we run sync code on a future cancellation?
      • defer-ish drop guards (that was an easy one :)
    • How do we run async code on a future cancellation?
      • Async drop et al
      • Spawn a new task for cleanup
        (talk more about problems, i.e. error propagation, GC-like properties, delays)
    • How do we write correct code?
      What if we lose data that's stuck in an idle future? think futures::select!
      https://tomaka.medium.com/a-look-back-at-asynchronous-rust-d54d63934a1c
      Rodionov: Tokio docs: cancel-safe functions
    • Rodionov: structured concurrency:
      • Structured Concurrency is a programming paradigm that lets asynchronous operations run only within certain scopes so that they form an operation stack like a regular function call stack. As the parent operation waits until all children complete, Structured Concurrency helps local reasoning of concurrent programs.
      • It is supported, see FuturesUnordered, tokio LocalSet. There are some rust specific problems related to lifetims which arise if you want to safely share data between scopes without copying or passing pointers e g Arc's. This is the problem with absence of async drop
      • Tokio issue: https://github.com/tokio-rs/tokio/issues/1879
  • Async: executor of your choice (5-12 min)

    • Tokio has mostly won (for now), but is it good? Good work stealing scheduler (like go's) etc
    • There are competitors: glommio (feature parity isn't there yet), how do we integrate them?
    • Lack of runtime-agnostic traits and APIs:
      • AsyncRead/AsyncWrite (tokio and futures-rs DO NOT agree on definitions!)
      • How do we spawn/cancel a future? (false dependency: we HAVE TO depend on the runtime, see global-runtime/futures-rs)
    • Not all hope is lost: see async-wg (workgroup), issues are being worked on
    • Rodionov: Deep dive into glommio, monoio, iouring (discussion)
  • Async: accindental calls of blocking functions (5 min)

    • Rodionov: Troubleshooting: tokio-console story, (experimental stall detector in glommio)
    • Rodionov: Unexpected goodness: mutex guards are NOT send, so they don't live across yield points!
    • Rodionov: NOT every sync primitives (e.g. Mutex) must be async! Which kind of mutex should you use
  • Async: sometimes combinators do not feel 1st class (4 min)

    • Lifetimes across funtion boundaries (mutable aliasing). What can we do?
    • Rodionov: anecodal evidence: problems with concurrent file APIs (open and_then sync_all leads to boilerplate)
  • Async: futures might be HUGE (2 min)

    • Several kilabytes per one future!
    • Troubleshooting: std::mem::size_of::<MyFuture>(), compiler pass for struct sizes

Rodionov: More about formal methods topics (approx 5 mins IF we have time)

Good to know (misc)

  • Code coverage

    • Newly stabilized in 1.60, previosly required export RUSTC_BOOTSTRAP=1 (workaround!)
    • Had to invent bespoke script for capturing LLVM coverage data and rendering
    • Prior art: tarpaulin, cargo-llvm-cov
  • Allocation story

    • Fallible allocations: WIP rust in linux kernel gave it another spin (some std APIs already stable)
    • Custom allocators: WIP (there's some support in std, but mostly nightly)
  • How to speed up the Rust compiler in 2022 (previously 2021, 2020 etc)

    • From the period 2021-11-11 to 2022-02-25 there were 303 improvements to the results of the rustc benchmark suite, many of which were over 10%, and only 21 regressions, as the following screenshot summarizes.
  • Incremental compilation woes

    • At any moment something remains broken! (just kidding :)
    • Tick-tock cycle: it's contantly turned off and then on and then off again