# 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](https://github.com/rust-fuzz/cargo-fuzz) (llvm libFuzzer)
- MUST: Rodionov: Testing frameworks: the built-in is good enough, but there's also [proptest](https://github.com/altsysrq/proptest) / QuickCheck (courtesy of Haskell)
- Paper: Rodionov: [Using Lightweight Formal Methods to Validate a Key-Value Storage Node in Amazon S3](https://dl.acm.org/doi/abs/10.1145/3477132.3483540) (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 Formal Methods Interest Group https://rust-formal-methods.github.io/
* 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](https://github.com/quickwit-oss/quickwit) Quickwit is the next-gen search & analytics engine built for logs. It is a highly reliable & cost-efficient alternative to Elasticsearch.
* [databend](https://github.com/datafuselabs/databend) A Modern Cloud Data Warehouse with the Elasticity and Performance both on Object Storage
* [materialize](https://github.com/MaterializeInc/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](https://github.com/tokio-rs/tracing))
- GOTCHA: futures may be self-referential, what about rust's guarantees? Talk about `Pin`
[Pin and suffering](https://fasterthanli.me/articles/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](https://tokio.rs/blog/2019-10-scheduler)
- 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](https://docs.rs/futures/latest/futures/task/trait.Spawn.html))
- Not all hope is lost: see async-wg (workgroup), issues are being worked on
- Rodionov: Deep dive into glommio, monoio, iouring (discussion)
- Completion vs Poll Based. Polling: During cancellationn for epoll you can stop polling a socket, but in completion you can receive a completion after future has been dropped. Thus causing use-after-free. Need further development, new traits, etc. Ongoing work:
- https://www.ncameron.org/blog/async-io-with-completion-model-io-systems/
* 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](https://docs.rs/tokio/latest/tokio/sync/struct.Mutex.html#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)
* prusti https://github.com/viperproject/prusti-dev Prototype verifier based on Viper
* stateright https://docs.rs/stateright/latest/stateright/ A model checker for implementing distributed systems. Can compile models to actors and actually run them
* Bright future: FERROCENE: RUST FOR CRITICAL SYSTEMS https://ferrous-systems.com/ferrocene/
## 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](https://github.com/xd009642/tarpaulin), [cargo-llvm-cov](https://github.com/taiki-e/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](https://nnethercote.github.io/2022/02/25/how-to-speed-up-the-rust-compiler-in-2022.html) (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