Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The Stun protocol is surprisingly easy to implement, but see my comment at https://news.ycombinator.com/item?id=40879547 about why I'd just use async instead of making my own event loop system.

https://gist.github.com/joshka/af299be87dbd1f64060e47227b577...



Thanks for the code! Going to pore over this.

I read the comment and I definitely agree (though it took me a while to get to where you landed), I think there are some benefits:

- More controllable/easy to reason about cancel safety (though this gets pushed up the stack somewhat). You just can't cancel a thread, but it turns out a ton of places in an async function are cancel points (everywhere you or some function calls .await, most obviuosly), and that can cause surprising problems.

- Ability to easily slap on both sync and async shells (I personally think it's not unforgivable to smuggle a tokio current thread runtime in as a dep and use block_on for async things internally, since callers are none the wiser)

Great comment though, very succinctly explained what I was getting at... I personally land on the "just make everything async" side of things. Not necessarily everything should be Send + Sync, but similar to Option/Result, I'd rather just start using async everywhere than try to make a sync world work.

There's also libraries like agnostic[0] that make it somewhat easier to support multiple runtimes (though I've done it in the past with feature flags).

> The problem with the approach suggested in the article is that it splits the flow (event loop) and logic (statemachine) from places where the flow is the logic (send a stun binding request, get an answer).

Very concisely put -- If I'm understanding OP's point of view, the answer to this might be "don't make the flow the logic"? basically rather encoding the flow as a state machine and passing that up to an upper event loop (essentially requiring the upper layer to do it).

Feels like there are at least 3 points in this design space:

- Sync only state machines (event loop must be at the outermost layer) - Sync state machines with possibly internal async (event loops could be anywhere) - Async everything (event loops are everywhere)

[0]: https://crates.io/crates/agnostic


also a bit late, but you've seen anyhow & miette right? noticed the color_eyre usage and was just wondering


yep - color_eyre is a better anyhow (and there's plans afoot to merge them into just one at some point[1]). Miette occupies a space that I generally don't need (except when processing data), while color-eyre is in the goldilocks zone.

[1]: https://github.com/eyre-rs/eyre/issues/177


Thanks for the pointer! Rustaceans are spoiled for choice with good error handling and libraries, great to have so many great choices.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: