
That's probably not where the threadKill is being sent *from*, it's where your thread received it.
Yeah, it's definitely where my thread received it. It's just sort of crazy, because when I get a ThreadKilled, it's almost always in Tiger.update. My handler does much slower things, such as connecting to a database and doing operations that can take tens of milliseconds, but somehow the ThreadKilled nearly always emanates from my Tiger.update. I even went so far as to wrap my Tiger.update in an IO operation that catches the ThreadKilled and tries the update again, and that "fixed" upwards of 90% of my thread deaths. Crazy...
It's hard to rule Snap timeouts out; try building snap-core with the "-fdebug" flag and running your app with "DEBUG=1", you'll get a spew of debugging output from Snap on stderr.
I'll give that a try, but whenever I've added any sort of printing to my handler to try to track things down, the issue goes away entirely. My toolkit for debugging race conditions is pretty weak; I usually have been able to think real hard and then fix them intuitively, but my intuition about Haskell is still weak enough that my normal approach isn't working :)