Hacker News new | past | comments | ask | show | jobs | submit login
When "blocked indefinitely" is not indefinite (well-typed.com)
41 points by g0xA52A2A on Jan 14, 2024 | hide | past | favorite | 10 comments



“indefinite” doesn't mean infinite or eternal or forever. It just means “end time unspecified/undetermined”.


Yes, but this is irrelevant, as the actual definition is in the article:

    A thread that is blocked on a TVar is considered blocked indefinitely if there is no reference [the GC "sees"] to that TVar from a running thread.
Edit: "GC" not "GHC".


Indeed, the from the linked ref to BlockedIndefinitelyOnSTM: <https://hackage.haskell.org/package/base-4.19.0.0/docs/Contr...>

>The thread is waiting to retry an STM transaction, but there are no other references to any TVars involved, so it can't ever continue.

But yes, presumably a different word would've been better.


Yes. Similarly MySQL will report as deadlocks when transactions are not in a deadly embrace but also in cases where A wants a lock held by B, and B (has for some time) wants a lock held by C, and C is just being slow not needing any more locks.


The article makes clear that the block end time is not unspecified or undetermined, rather it should be immediate, as the queue still has data.


Very nicely written article.. and yeah, stable-pointer all the things! meme.

That said, these issues are why I'm considering switching away from Haskell long-term... but that's not easy, I'm deeply invested, and all the other features let me be really productive / creative. But the occasional weird runtime bug or timesink that takes a week to track down.. could live without that.

(There are ways to use the concurrency and queuing primitives like these kind of safely but it needs a deep expertise, there are too many non-obvious parts where you can let an exception slip through at the unintended place or otherwise get yourself burned. Lack of stack traces don't help much either, though that can be somewhat orthogonal)


> I'm deeply invested

I used to think that too, and a trusted mentor suggested the Sunk Cost Fallacy was in play https://www.verywellmind.com/what-is-sunk-cost-fallacy-71068....

Walking away from Haskell was like leaving a bad marriage. Now, in retrospect, it's clear I stayed too long.


While I don’t know Haskell or GHC, that sounds like a bug in the runtime.

My understanding:

- Deadlock detection is a feature some language runtimes can provide.

- To my knowledge there’s no reasonable path of recovery from within the process (broad sense of the term) itself.

- If you have process isolation then a parent or supervisor can kill and respawn. (Is this what Erlang does?)

- Deadlocks are only theoretically detectable in the cases where the runtime can trace the “path” to something it knows about. This may include runtime objects like channels and mutices, but certainly does not include IO etc. For example: program is currently waiting on a tcp socket with no timeout.

- As such, deadlock detection is at most moderately useful for typical application debugging and development workflows.

Personally I would much rather have easy access to a “what are processes currently blocked on” list than “the runtime is so smart it will error out automagically” kind of thing.


A slightly different form of deadlock detector can still be really useful for portions of the system that are not unbounded network IO. I agree that predicting forward progress from in-memory state like Haskell seems to be doing is more or less useless in the presence of IO. But you can instead use some measure of forward progress and a simple long timeout (like 10-60 seconds) to empirically determine the system is stalled.

E.g., you might reasonably implement timeouts on slow network clients or otherwise have a way to idle them, so it is still a problem if the system does not make forward progress in 10 seconds or whatever. Or if your service manages all access to disk, you can expect bounded IO from disks that have not failed. Then you can take some debugging action (development) or maybe restart the service (prod) or some combination of the above when a deadlock is detected in an empirical way (no forward progress in a time period).


> While I don’t know Haskell or GHC, that sounds like a bug in the runtime.

That's what the article is about, workarounds for that problem (that has been known for 8 years now).

https://gitlab.haskell.org/ghc/ghc/-/issues/10793




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: