HNHacker News
TopNewBestAskShowJobs

fasterthanlime

1,419 karma · joined August 8, 2014

say hi, be kind
submissionscomments
fasterthanlime··on Migrating from Warp to Axum
Oh I wrote that code in anger forever ago, it had the merit of still working when I did the last round of cleanups on my website.

I could've sworn at some point some paths had something slightly more involved (strip slashes, some starts_with or trim_prefix, etc.) but the snippet as you've copied it is certainly... not great.

fasterthanlime··on Migrating from Warp to Axum
I'm not sure what you mean by "pull-based", but you can make the whole thing single-threaded with `#[tokio::main(flavor = "current_thread")]`

See https://docs.rs/tokio/latest/tokio/attr.main.html

fasterthanlime··on Migrating from Warp to Axum
Fair, but if you were writing a web application on top of hyper directly, you probably wouldn't use one tower layer per route, which is somewhat equivalent to what warp does.

When I wrote this I worked at a company where the main Rust codebase had, uh, perhaps too many tower layers.

fasterthanlime··on Migrating from Warp to Axum
Yeah, clippy will yell at you if you use a match with a single arm - I personally don't hate matches with a single arm, but I'd rather not fight clippy (ie. come up with my own clippy config, enforce it onto every project I maintain etc.)
fasterthanlime··on Migrating from Warp to Axum
Request extensions (a feature of the `http` crate, not specifically hyper/warp/axum) are "just" a typemap, which is "just" a HashMap where keys are TypeIDs rather than strings. It's slightly less footgunny than something like Go's Context, although I still dislike it because checking for the presence of something happens at runtime only, so if you're messing with middleware composition, it's still too easy to accidentally get it wrong.
fasterthanlime··on The HTTP crash course nobody asked for
The RFCs themselves are pretty dry, if that's your thing — https://httpwg.org/ has the freshest ones.
fasterthanlime··on The HTTP crash course nobody asked for
You know how some movie fans will sometimes pretend the sequels to some franchise don't exist? HTTP is the opposite.
fasterthanlime··on The HTTP crash course nobody asked for
My whole thing is that I'm teaching Rust /while/ solving interesting, real-world problems (instead of looking at artificial code samples), so, if someone wants to write the equivalent article with Python, they should! I won't.
fasterthanlime··on The HTTP crash course nobody asked for
The article covers using Wireshark to decrypt TLS traffic using Pre-Shared Master Secrets!
fasterthanlime··on The HTTP crash course nobody asked for
I tend to agree with you there, however the thing I'm replacing does HTTP/2, and HTTP/3 is yet another can of worms as far as "production multitenant deployment" goes, so, that's what my life is right now.

As far as learning goes, I do think HTTP/2 is interesting as a step towards understanding HTTP/3 better, because a lot of the concepts are refined: HPACK evolves into QPACK, flow control still exists but is neatly separated into QUIC, I've only taken a cursory look at H3 so far but it seems like a logical progression that I'm excited to dig into deeper, after I've gotten a lot more sleep.

fasterthanlime··on The HTTP crash course nobody asked for
Against my better judgement, the article /does/ go over H2 (although H3 is all the rage right now).

For TLS, I recommend The Illustrated TLS 1.3 Connection (Every byte explained and reproduced): https://tls13.xargs.org/

fasterthanlime··on MiniRust
Cool Bear has been making guest appearances in a couple places already! I do not intend to pay lawyers to pursue anyone who uses them without permission but I appreciate being asked first — it lets me keep track of where Bear travels.

My only worry regarding Cool Bear is the licensing of the two pieces of artwork: I bought them a while ago on some stock image website but the terms weren't super clear, so I might need to revisit that. Since then I've commissioned drawings of bear and myself (5 variants each) but I haven't had a chance to use those yet — they're not monochrome, which makes dark mode awkward.

fasterthanlime··on MiniRust
RalfJ if you see this: you have my permission to use Cool Bear on your blog. Thanks for asking!
fasterthanlime··on Some Thoughts on Zig
This particular example is trivially restructured into a version that passes the current borrow checker: https://play.rust-lang.org/?version=stable&mode=debug&editio...

It isn't the gotcha you're looking for.

fasterthanlime··on When rustc explodes
> Try to find the current number of running tasks being managed by tokio…

As a heavy user of async Rust in production (at a couple places), resource leaks / lack of visibility into that has been a top issue.

In this area, tokio-console[1] is an exciting development. I have high hopes for it and adjacent tools in the future. (Instrumenting your app with tracing+opentelemetry stuff can help a lot, too).

Until those become featureful/mainstream enough, Go has the upper hand in terms of "figuring out what's going on in an async program at any given time".

[1]: https://lib.rs/crates/tokio-console

fasterthanlime··on When rustc explodes
Quick aside: if you're willing to live the nightly life (unstable rustc), the `type_alias_impl_trait` feature gets you most of the way to "async trait methods". You still have to have a `Future` associated type, but in impl blocks, it just becomes `type Future = impl Future<Output = Blah>`, and then the compiler infers what the concrete (and probably unnameable, if you use async blocks) type is - no need to mess with `Pin<Box<T>>`.

The most egregious code comes when implementing one of the `AsyncRead`/`AsyncWrite` traits or similar, and that can come up a bunch in backend services, for example if you want to record metrics on how/when/where data flows, apply some limits etc. I'm curious how the ecosystem will adapt once async trait methods land for real.

fasterthanlime··on When rustc explodes
> but its currently at like 98

Come on now. There's two chasms between "an academic paper", my blog, and "a blog with minion/the office reaction GIFs".

The amount of humor is finely-tuned so that it's not /too/ distracting from the actual technical topic at hand (of which there's always one, I'm not a sit-down comic), but it also filters out folks who'd rather focus on the form than the content / take themselves too seriously.

Looks like the net caught you! Hi!

fasterthanlime··on When rustc explodes
> Don't use the `async` ecosystem.

I want to make it /very/ clear that async isn't to blame at all for the pathological build times described here. It's a bug about traits and lifetimes, both very core concepts of Rust that you deal with even if you stay away from async code.

async rust will certainly be more ergonomic once some more improvements land (hopefully later this year), but I don't feel like it deserves all the sighs it's been publicly getting these past few months. (And I /love/ to complain. I've written pieces named "Surviving Rust async interface", "Getting in and out of trouble with Rust futures", "Pin and suffering", etc.)

> Prefer dynamic dispatch to monomorphization (i.e., use fewer generics).

Unless you hit a pathological case as shown in the article, it tends to not be _that_ bad, especially if you enable `-Z share-generics=y` (unstable still, yet enabled by default for debug builds if I remember correctly).

Overall still solid advice - although "use fewer generics" sometimes turns out to be "just turn a big generic type into `Box<dyn Trait>`" (it's not _just_ boxing, that would be `Box<T>`). That's what axum[1] does with all services, and it's never had the compile times issues warp[2] had, for example.

> Don't use proc macros (i.e., don't depend on the `syn` crate, even transitively).

Good news there, I hear there's some progress on the proc-macro bridge (which improves macro expansion performance) AND "wasm proc-macros". I hope this piece of advice will be completely irrelevant in a year (but for now, it's spot-on. using pin-project-lite instead of pin-project is worth it, for example).

[1] https://lib.rs/crates/axum

[2] https://lib.rs/crates/warp

fasterthanlime··on When rustc explodes
Author here: I honestly expected it to be much worse. The tracing integration in particular is fantastic - being able to just slap a `#[instrument(...)]` attribute on any function and then be able to filter which spans you want to see is kind of a superpower.

That said I think much could be improved, still. I only breezed through the perf/nperf stuff because I've used them before, and through the self-profiling stuff because rustc devs helped me with it.

I would've killed for a REPL while I was working on this (or a server architecture so I could write my _own_ rustc queries), and step through them, etc. I like Kate's approach to this[1] - I'd just like something a little more... interactive.

What do _you_ think it should look like? I feel like a ton of good ideas come from folks who "simply didn't know it was impossible" (more accurately: haven't been trained to accept to work with subpar tools). I'm excited to try out Pernosco[2] for example, it seems like a much-needed rethink of debuggers.

[1]: https://twitter.com/thingskatedid/status/1386077675211526148

[2]: https://pernos.co/

fasterthanlime··on Remote Development with Rust on Fly.io
The reason is that it takes me longer to remember the order of arguments for "grep" than it takes me to write the pipe. I also find that order more natural.

I'm also trying to carbon-offset all my useless uses of cat by writing ops glue in Rust instead of bash. Hopefully I'm net positive.

fasterthanlime··on Remote Development with Rust on Fly.io
(Author here) So, I've been running this exact same setup for my dev box and I think you're overestimating how often the whole IPv4 space is being scanned.

What helped me at first was that I only set up an IPv6 address, since I have IPv6 at home. Scanning the whole IPv6 space is impractical, I've never seen an IPv6 address of mine being hit randomly (unless there's a public DNS record for it, or it's leaked some other way).

But then I had to access my remote work environment from a laundromat (don't ask..) and I added an IPv4. I can see in the logs it's been woken up by some scans (some IP in the Baltics).

Moving the SSH server to a non-standard port won't really help here. Using a VM of the smallest size to act as a bastion would essentially solve the cost problem - that's something you can do on fly today. For even better solutions... there'd need to be some collaboration from fly-proxy.

I've been wanting to add /some/ firewall capabilities to it. If there were an API for that, you could run "knock" on another service, which would allowlist your address for a while on your actual "remote work VM" service.

I also wanted to suggest "just using ipv6" (set up wireguard, boom, you're now in the VPN of your organization, where your VM lives, so just don't allocate a public IP for it and you're good), but the problem there is that it currently doesn't wake it up.

Anyway this comment is a rich source of feature ideas, please keep them coming.

fasterthanlime··on I won free load testing
sammy811 is claiming responsibility for the small attack on the video platform.

Nobody's claimed responsibility for the main attack, but the answer is probably "mostly Tor + a bunch of open proxies". There's probably easily available databases of those available somewhere?

fasterthanlime··on I won free load testing
I looked for that kind of data structure for 30 seconds in the ipnet crate itself, didn't find it, noticed there were only 23 IP ranges and decided it was fine.

(Keep in mind this happened during the attack, so compromises)

fasterthanlime··on I won free load testing
It happened after I left, I don't think it's my story to tell (and I think they have higher priorities than telling that story).
fasterthanlime··on I won free load testing
The article covers this in great detail. Do a search for "fair enough" to jump to the relevant section.
fasterthanlime··on I won free load testing
I snitch-tagged Digital Ocean and other VPS providers involved in the attack, but didn't expect much. They're much bigger than this: what's a big deal for my toy server is barely a blip on their radar.

And realistically, there's only so much they can do about someone running Tor exit nodes / an open proxy on their infra. Everyone in the cloud space has been fighting that off (and miners) for years, it's one arms race among many.

fasterthanlime··on I won free load testing
Thanks for the context, I fixed those up. This was my first time looking up AS for additional info and it was a lot of fun.
fasterthanlime··on I won free load testing
Why were some only some requests Range requests? (the status codes included 206 and 200)
fasterthanlime··on I won free load testing
Indeed. fly.io encouraged me to move projects there, but since I budget my side projects as if they were an actual business, parts of the pricing page turned me off.

For the time being, I've decided that getting insights into "how well the platform worked for me" was more valuable for me, so my video platform is staying there, but I've initiated multiple discussions about pricing and I intend to keep doing so until I'm happy with the answer.

fasterthanlime··on I won free load testing
mTLS certainly seems like the the most expensive option here (not that expensive outside attacks, though).

S-tier implementations include: firewall rules or a BPF program, or a VPN-based approach (like Cloudflare Tunnel). The way I did it is fine for small-scale attacks like that one, but a large enough attack will have you spend too much time on syscalls and waste valuable kernel resources.

I'd love to read a write-up about how these different approaches perform in practice, because this is largely gut feeling / the popular wisdom that "the sooner you block, the better".

← PreviousPage 2 of 6Next →