HNHacker News
TopNewBestAskShowJobs

hardwaresofton

12,853 karma · joined January 16, 2013

writing at vadosware.io
submissionscomments
hardwaresofton··on From Async/Await to Virtual Threads
> Personally I'm more annoyed of async-Rust itself than not having a blessed async solution in-tree. Having to just Arc<T> away things here and there because you can't do thread::scope(f) honestly just demonstrates how stackless coroutine is unreasonably hard to everyone.

Yeah as annoying as this is, I think it actually played out to benefit Rust -- imagine if the churn that we saw in tokio/async-std/smol/etc played out in tree? I think things might ahve been even worse

That said, stackless coroutines are certainly unreasonably hard.

> Back to the original topic, I bring this up because I believe the performance advantages claimed in these "fibers bad" papers are superficial, and the limit is almost the same (think 1.00 vs 1.02 level almost), even in languages which consider raw performance as a selling-point. In case you need the absolutely lowest overhead and latency you usually want the timing to be as deterministic as possible too, and it's not even a given in async-await solutions, you still need to be very careful about that.

Yeah, I don't think this is incorrect, and I'd love to see some numbers on it. The only thing that I can say definitively is that there is overhead to doing the literal stack switch. There's a reason async I/O got us past the C10k problem so handily.

One of the nice things about some recent Zig work was how clearly you can see how they do their stack switch -- literally you can jump in the Zig source code (on a branch IIRC) and just read the ASM for various platforms that represents a user space context switch.

Agree with the deterministic timing thing too -- this is one of the big points that people who only want to use threads (and are against tokio/etc) argue -- the pure control and single-mindedness of a core against a problem is clearly simple and performant. Thread per core is still the top for performance, but IMO the ultimate is async runtime thread per core, because some (important) problems are embarassingly concurrent.

> Let alone Python.

Yeah, I' trying really not to comment much on Python because I'm out of my depth and I think there are...

I mean I'm of the opinion that JS (really TS) is the better scripting language (better bolt-on type systems, got threads faster, never had a GIL, lucked into being async-forward and getting all it's users used to async behavior), but obviously Python is a powerhouse and a crucially important ecosystem (excluding the AI hype).

hardwaresofton··on From Async/Await to Virtual Threads
Rust vs Go is IMO not even a reasonable discussion to have -- you really have to be careful on the axes for which you compare them for the thought exercise to make any sense.

If you want a productive backend language that developers can pick up quickly, write code in, and be productive relatively quickly and write low latency applications, Go is an easy winner.

If you want a systems language, then Rust is the only choice between those two. Rust is harder to pick up, but produces more correct and faster code, with obviously a much stronger type system.

They could be directly comparable, but usually only if your goal is as abstract as "I need a language to write my backend in". But you can see how that question is a very difficult one to pull meaning from generally.

> How often do we see "stackless coroutine" listed as advantage in Rust vs Go for network programming flamewars?

I'm just going to go out on a limb and say network programming is bar none more efficient in Rust. I could see C/C++ beating out Rust in that domain, but I would not expect Go to do so, especially if you're reaching for unsafe rust.

Again, it also depends on what you mean by "network programming", and whether development speed/ecosystem/etc are a concern.

To avoid the flamewars and stay on topic, it's one of those things that is just a fundamentally limiting choice -- most will never hit the limit (most apps really aren't going to do more than 1000RPS of meaningful requests), but if you do actually need the perf it's quite disappointing.

People are very annoyed with Rust for not having a blessed async solution in-tree, and while it's produced a ton of churn I think it was ultimately beneficial for reasons like this. You can do either one of these in Rust, the choice isn't made for you.

That said, the OP's suggestion seems to be adding virtual threads on rather than swapping out asyncio for virtual threads, so maybe there's a world where people just use what they want, and python can interop the two as necessary.

hardwaresofton··on From Async/Await to Virtual Threads
If I'm understanding the suggestion, the proposed python virtual threads are ~= fibers ~= stackful coroutines.

I have this paper saved in my bookmarks as "fibers bad":

https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p13...

AFAIK sync/await and stackless coroutines are the most efficient way to do async operations as far as I can tell, even if they are a unwieldly and complicated. Is there something to be gained here other than usability?

Python is certainly in the business of trading efficiency and optimal solutions for readability and some notion of simplicity, and that has held it back (and all the programmers that overindex on the pythonic way, it's incredibly sad that all of modern ML is essentially built on python) IMO, but the language is certainly easy to write.

[EDIT] - wanted to put here, people spend a lot of characters complaining about tokio in Rust land, but I honestly think it's just fine. It was REALLY rough early on, but at this point the ergonomics are quite easy to use and understand, and it's quite performant out of the box. It's not perfect, but it's really quite pleasing to use and understand (i.e. running into a bug/surprising behavior almost always ends in understanding more about the fundamental tradeoffs and system design for async systems)

Swift doing something similar seems to be an endorsement of the approach. In fact, IIRC this might be where I saw that first paper? Maybe it was a HN comment that pointed to it:

https://forums.swift.org/t/why-stackless-async-await-for-swi...

Rust and Swift are the most impressive modern languages IMO, the sheer amount of lessons they've taken from previous generations of PL is encouraging.

hardwaresofton··on FoundationDB: From idea to Apple acquisition [video]
Note that FDB can support other paradigms on top of KV

https://foundationdb.github.io/fdb-record-layer/SQL_Referenc...

Also IIRC Apple uses FDB at tremendous scale:

https://read.engineerscodex.com/p/how-apple-built-icloud-to-...

hardwaresofton··on Ask HN: I built an ML pipeline automation framework – how can I improve it?
No worries — Good luck out there riding the wave!
hardwaresofton··on Ask HN: I built an ML pipeline automation framework – how can I improve it?
Yeah really didnt want to discourage you but I feel like its totally greenfield in metaflow land (they just open sourced right?) and if you improved stuff there you’d have superb market fit as teams tried it out.

Cargo culting netflix’s tech is usually a bit questionable but maybe not this time!

> The ML space is evolving at a crazy pace, and I totally get that people who are deep in the field with real deadlines don’t have the bandwidth to adopt yet another framework. That’s why I’m not aiming to build a framework from scratch to compete, but rather to build a productivity and automation layer on top of existing tools like Metaflow.

Sorry looks like this was my Lack of proper reading!

More concrete feedback:

- Docs link in readme 404s

- get to code/demonstration or your unique advantage as fast as possible in README (“complete pipeline code” on this page: https://brkcvlk.github.io/MLFCrafter/getting-started/first-p.... ?)

- if its built on metaflow be upfront about it? The value prop would be saving time/enforcing a golden path?

- “<x>Crafter” is probably noise that should be deleted

- can you collapse some of the setup lines

- it might be nice if you could feed inputs to the pipeline as a whole, then you could use the context management APIs in Python (“with” IIRC?)

[EDIT] yeah metaflow has definitely been around for a while!

hardwaresofton··on Ask HN: I built an ML pipeline automation framework – how can I improve it?
Not an ML guy, but getting people to use a new framework is going to be super hard in a field like ML that is churning at such an insane rate. I’m not an insider but I just can’t imagine anyone with real skin in the game and deadlines has the time to jump in.

It’s tough but would you be willing to consider adding value to the metaflow ecosystem instead?

hardwaresofton··on Rust running on every GPU
Thanks for the pointer and thanks for all the contributions to the huge amount of contributions around rust-gpu. Outstanding work
hardwaresofton··on Rust running on every GPU
This is amazing and there is already a pretty stacked list of Rust GPU projects.

This seems to be at an even lower level of abstraction than burn[0] which is lower than candle[1].

I gueds whats left is to add backend(s) that leverage naga and others to the above projects? Feeks like everyone is building on different bases here, though I know the naga work is relatively new.

[EDIT] Just to note, burn is the one that focuses most on platform support but it looks like the only backend that uses naga is wgpu... So just use wgpu and it's fine?

Yeah basically wgpu/ash (vulkan, metal) or cuda

[EDIT2] Another crate closer to this effort:

https://github.com/tracel-ai/cubecl

[0]: https://github.com/tracel-ai/burn

[1]: https://github.com/huggingface/candle/

hardwaresofton··on When Is WebAssembly Going to Get DOM Support?
Thanks for sharing your thoughts -- I think I have a clearer grasp of what you were getting at now.

> Honestly, I can't believe you're asking me this! You're so far in the weeds of the WASM component model that you have no idea what the problem is. It's really silly to ask what the "most important blockers" are, as if it's a list of bugs that can be fixed.

This is a pretty unproductive way to converse -- I asked because I wanted to know what you thought the blockers were. Problems can be broken down into smaller ones, and getting on the same page with regards to the problem is key to producing better software and meeting user needs.

We can't solve a problem if we can't enumerate it's pieces, and what people want can be varied.

> Today, if you take a UI-focused DOM-heavy web app that makes lots and lots of DOM API calls (i.e. most JS web apps ever written) and try to rewrite it in Rust, you'll have to cross the boundary between JS and WASM over and over again, every time you use a DOM API. Every time you add/remove/update an element, or its styles, or handle a click event, you'll cross the boundary.

At present, you must cross two boundaries. One out of WASM and one in JS into the engine.

> And it's not just strings. All JS objects that you need to do actual work with have to be serialized/deserialized in this way, because WASM only knows about bytes, arrays, and opaque pointers. DOM elements/attributes, DOM style properties, DOM events (click events, keyboard events, etc.), all of them get slow when you transfer them in and out of WASM land, even with reference types, because of serialization/deserialization.

> WASM interface types will make it easier to call JS from WASM, but as long as you're still calling JS in the end, rewriting in Rust will never make a DOM-heavy web app faster than writing it in JS.

This is untrue, Wasm interfcace types make it easier to call any language from Wasm. This includes the languages that browsers are written in, namely C++, Rust, etc. This opens a path to optimization and possible direct application of the APIs that JS uses today.

Also as a side note -- increased performance of DOM operations is not the only goal worth pursuing. For example, performance parity with JS is also a worthy goal, because holistically Wasm as a compute option has other benefits.

> The only fix, as Daniel's article explains, would be to standardize a low-level DOM API, one that didn't assume that you can use JS strings, objects+properties, exceptions, promises, etc. This would be an unimaginably large standardization project. > > You couldn't use WebIDL at all; you'd need to start by defining a new "low-level WebIDL." Then, you'd start standardizing the entire DOM API, all over again (or at least the most important parts) in low-level WebIDL, and then browser vendors could start implementing the low-level DOM API.

Introducing a completely new low level DOM API is ideal, but is naive in practice. WebIDL is the lingua franca for browser integration at this point, for the one language that actually has such support.

Standards are hard to create (especially from scratch), we cannot control how fast browsers implement or the priorities of browser companies.

> Then WASM could start calling that API directly. And maybe then you could rewrite web apps in Rust and have them get faster.

Embedders of WebAssembly components (i.e. browser engines written in C++/Rust/etc) may choose to fulfill the imports of WebAssembly components however they'd like. It is indeed possible that a browser engine, upon instantiating a WebAssembly component that does DOM work, fulfills the WebIDL contract with more direct bindings to the underlying operations.

There will always be at least one hop across a boundary -- WebAssembly. That said, it is possible for that one hop to be optimized by embedding engines.

For any such optimization to even be possible (with or without the component model), standards bodies and browser vendors must agree on what the interface they are about to speak is. They have already agreed on WebIDL, so porting that is a good place to start independent of whether creating a completely new standard is feasible.

> So, what's the most important blocker? (gesture toward the universe) All of it??

Concretely, what needs to be optimized is DOM calls. They are not impossible, they are just inefficient at present. That is a problem that can be worked on, and I don't think it's productive to say "all of it". There are many discrete steps that need to be accomplished to get to cross-browser consistently performant DOM support for components, and it's reductive to assume there is only one step to be done/that it all gets done at once.

A realistic path to optimization of any more performant interaction with underlying browser engine primitives is working with the interfaces they already have. WebIDL to WIT support (i.e. cross browser and cross platform as it's WebAssembly native) is a step in that direction, and as such is forward progress. If we can't agree there, we'll have to agree to disagree.

At this point it's a matter of working with browser vendors on their embeddings, and getting whatever bindings we agree on to be performant inside the relevant browser engine.

hardwaresofton··on When Is WebAssembly Going to Get DOM Support?
> What developers are looking for is a way to take UI-focused DOM-heavy web apps, RIIR, and get a performance improvement in browsers.

Could you expand a bit on waht you expect would make this possible? What would you list as the most important blockers right now stopping people from getting there in your mind?

hardwaresofton··on When Is WebAssembly Going to Get DOM Support?
Thanks for using and contributing to Jco!

> (the async and stream support coming in Preview 3 are the real missing pieces for my usecases).

Currently this is a huge focus of most of the people working on stuff, and Jco is one of the implementations that needs to be done before P3 can ship, so we're hard at work on it.

> exciting step towards real useful polyglot libraries I have seen in years

I certainly agree (I'm biased) -- I think it's going to be a kind of tech that is new for a little bit and then absolutely everywhere and mostly boring. I think the docker arc is almost guaranteed to happen again, essentially.

The architectural underpinnings, implementation, and possibilities unlocked by this wave of Wasm is amazing -- truly awesome stuff many years in the making thanks to many dedicated contributors.

hardwaresofton··on We built an air-gapped Jira alternative for regulated industries
AGPL continues to be the future of F/OSS

https://vadosware.io/post/the-future-of-free-and-open-source...

Dread it, run from it, AGPL still arrives. Sustainable F/OSS is the most likely to-still-be-active-5-years-from-now kind of F/OSS.

hardwaresofton··on When Is WebAssembly Going to Get DOM Support?
Disclaimer: I work on Jco, one of the user-facing Bytecode Alliance WASM JS ecosystem projects

Just a note, but there is burgeoning support for this in "modern" WebAssembly:

https://github.com/bytecodealliance/jco/tree/main/examples/c...

If raw WebIDL binding generation support isn't interesting enough:

https://github.com/bytecodealliance/jco/blob/main/packages/j...

https://github.com/bytecodealliance/jco/blob/main/packages/j...

https://github.com/bytecodealliance/jco/blob/main/packages/j...

Support is far from perfect, but we're moving towards a much more extensible and generic way to support interacting with the DOM from WebAssembly -- and we're doing it via the Component Model and WebAssembly Interface Types (WIT) (the "modern" in "modern" WebAssembly).

What's stopping us the most from being very effective in browsers is the still-experimental browser shim for components in Jco specifically. This honestly shouldn't be blocking us at this point but... It's just that no one has gotten around to improving and refactoring the bindings.

That said, the support for DOM stuff is ready now (you could use those WIT interfaces and build DOM manipulating programs in Rust or TinyGo or C/C++, for example).

P.S. If you're confused about what a "component" is or what "modern" WebAssembly means, start here:

https://component-model.bytecodealliance.org/design/why-comp...

If you want to dive deeper:

https://github.com/WebAssembly/component-model

hardwaresofton··on Async I/O on Linux in databases
Great article -- it's really subtle to see where the real perf gains came from but will try and summarize it for those who may come after:

The gains are from batching and doing work in-between. io_uring does "batching at a distance", and the DB can write to memory and perform operations in between. When io_uring checks the queues (intent/operation), it will find more than one operation, and do them all at once.

You don't lose durability with this setup -- you just do more speculative work (if you got the worst possible crash at the worst possible time), and if a bunch of things completed (because io_uring did them all at once) you get more confirmations you can send back faster.

Latency MIGHT suffer, but throughput would (and does) increase.

hardwaresofton··on Async I/O on Linux in databases
Nope, Other commenter noted it:

https://www.postgresql.org/docs/current/runtime-config-wal.h...

Don't use synchronous_commit = off is durability ~= 0 (i.e. "I hope the write made it to disk")

hardwaresofton··on The borrowchecker is what I like the least about Rust
> Not that I think Erlang manages to be a nail gun; it has enough idiosyncrasies that the comparison is not terribly accurate. Still, “need” is doing a lot of heavy lifting in that sentence.

Yeah it was a bit vague -- I should have said something more like "not many developers/teams/companies need telecom level uptime and resilience enforced at the single system level". In reality, most groups have solved this by redundancy and building multiple systems/distributing them. You could argue it's the wrong solution, but it's been good enough for so many people that... it's probably fine.

hardwaresofton··on The borrowchecker is what I like the least about Rust
> Nobody cared about Erlang back then and nobody does today. > > I write Erlang for a living.

I think this is incredibly correct and obviously personally true for you but I'd like to add one more thing from the peanut gallery.

No one really needs Erlang either. Turns out most problems are just fine not being modeled in the way that Erlang wants to model problems.

hardwaresofton··on Trying Guix: A Nixer's impressions
> Does it matter if it translates to systemd services under the hood or not?

I think so, because that's what most people are familiar with maintaining/configuring. Systemd at this point is quite robust, and it's sprawling ecosystem has a lot of functionality. Perhaps more importantly, this is the stuff you'll find the most support/integrations for.

hardwaresofton··on Trying Guix: A Nixer's impressions
> The downside is, of course, that more and more of the linux userland depends on systemd. That is bound to become a problem sooner or later.

This is the main problem. Systemd has the most eyes, and the most active development, and I just don't want to spend innovation tokens on that as well.

> My biggest gripe is that I would like to have a simpler way to install it onto my computer. I need nonguix to even boot on one of my computers, but I really really hate doing that because doing a system install from nonguix has a tendency to break things for me later on.

That's a huge issue. Which also reminds me, this kind of requirement is dead in the water for the GPU era, at least until there are sufficiently F/OSS high quality drivers (which may be never).

Maybe the answer here is to just use only guix the package manager

hardwaresofton··on Shutting Down Clear Linux OS
It's not that simple actually -- this kind of thinking might leave you working on mainframes in 2000 (or even now) which is obviously a mistake.

It requires a certain taste. There's a skill involved.

> Just be smart and selective about your choices, and avoid compromising.

This is a very "draw the rest of the owl" kind of statement

hardwaresofton··on Shutting Down Clear Linux OS
Sure, but the counter is that you're going to be very late to some new foundational tech (ex. Kubernetes) that are legitimately useful. There are benefits to being early to a trend that has legs
hardwaresofton··on Shutting Down Clear Linux OS
sure but this approach is limited, ChatGPT would have failed this test.
hardwaresofton··on Shutting Down Clear Linux OS
I’m assuming a friendly tone here, and in a similar tone its funny because I also think Nix is not adopted because its benefits just aren't worth the cost to users (devs)
hardwaresofton··on Shutting Down Clear Linux OS
Hard disagree here, corporations almost always have the biggest pockets to fund continued R&D.

There’s a tension there, but this is why it’s a skill — theres no simple rule. Fully open source community governed projects can be some of the most obviously good to ignore.

hardwaresofton··on Shutting Down Clear Linux OS
Knowing which projects/languages/frameworks to invest time into and which to skip (even if they produce useful subprojects) is a superpower these days.
hardwaresofton··on Trying Guix: A Nixer's impressions
Guix SD will never catch on as long as they force non-systemd management. I don’t care to try Shepherd. Systemd is good enough and it has won.

> I had to use nonguix to get internet working on the machine, which had very immediate technical effects that bring me to

Stuff like this will

The main reasons I’m interested in guix:

- it uses a known-good language (lisp)

- IIRC it is more repeatable (the contents used in derivations play into the hash).

- It has a full source bootstrap

Maybe someone with a focus on improving UX needs to build one of these afresh.

hardwaresofton··on Incus – Next-generation system container, application container, and VM manager
I think of this more as routing than service discovery -- there's nothing in k8s that tells you how to reach a related service, you still need to know it's IP or DNS name and reach out.

Incus is not bridged by default, so you have to do more work to get to that starting point (IP addresses), there's some configuration for IPAM as well.

Incus also does not provide name resolution support out of the box, contrasted with kubernetes which will modify resolution rules via the Kubelet. Incus can do this via systemd i.e. at the system level for traffic into a specific Incus node.

> If the system that runs Incus uses systemd-resolved to perform DNS lookups, you should notify resolved of the domains that Incus can resolve.

This, combined with BGP[0] would give you a mesh-like system.

So basically, Incus definitely doesn't do it out of the box -- you need to do your own plumbing.

To be clear, I stand corrected here -- this is a legitimate difference between the two, but it's not that it's impossible/completely out of scope with Incus, it's just that it's not built in.

[0]: https://linuxcontainers.org/incus/docs/main/howto/network_bg...

hardwaresofton··on Incus – Next-generation system container, application container, and VM manager
Hmmn... I think it really depends on what you call "service discovery", but I'd note that k8s doesn't give you something as complicated as Consul either -- by default, you get DNS & IP networking for service discovery, which Incus also supports.

If you mean service discovery as in being able to use the k8s API (ex. to find service manually) from inside your application, then incus allows for that too..

Maybe the key difference you're pointing at here is that Incus does not give you one huge network (where by default everything is routable), so you have to set up your own bridge networks:

https://linuxcontainers.org/incus/docs/main/explanation/netw...

https://linuxcontainers.org/incus/docs/main/reference/networ...

I could definitely agree here that Incus is more unencumbered in this respect

hardwaresofton··on Zig's New Async I/O
Ah good point -- sans I/O as described in that second link is a bit more narrow than what Zig is doing here. The sans I/O discussed there is more for protocols specifically and less for general I/O.

I guess a better name for this approach might be "explicitly managed I/O".

← PreviousPage 4 of 34Next →