Prevent socket specs from hanging the main fiber#9437
Prevent socket specs from hanging the main fiber#9437jhass wants to merge 1 commit intocrystal-lang:masterfrom
Conversation
5b06c4f to
0b063c4
Compare
|
I don't like that the helpers remove the actual method call from the direct spec code. The call to socket = with_timeout { server.accept }This would mean we only need a single helper method. It would also be great if the helper handled exceptions raised in the spawned fiber. |
Handled how? Basically no spec code does that right now.
Well, it's just there to prevent FD leaks for specs that don't use |
|
Rescue the exception, send it to a channel, add that channel to the Spec helpers |
|
This is more than a refactor, it actually fixes the specs hanging themselves in some build environments or error conditions rather. I wouldn't be too surprised if the random preview_mt specs hangs we see are even caused by this (not saying it fixes them properly for MT, just that it might no longer hang). |
|
I was hesitant about adding more complexity to the specs by adding extra fiber plus channels to handle Line 274 in e75e429 That |
|
Mmh, what I liked here is that I could imagine potentially a |
|
Yup, I understand, but I don't want to mix channels and selects where it's not needed. Let's keep things simple as possible. I know a hanging spec is hard to debug, but it's even harder if we mix things that often causes trouble in multithreaded environments. |
|
I mean, I understand what you're trying to accomplish, but in that case should we add a |
|
I wouldn't be very opposed to that! Of course it should be possible to set the actual timeout value or disable it entirely if you know what you're doing. Also probably to set the default value per context. But capping a spec to something like 10 seconds per default sounds entirely sensible to me. |
|
Yup, totally doable, but that would work very differently than creating fibers and channels, and work more tightly with the runtime instead. |
|
Are you sure? |
|
No, because even in MT the fibers work in cooperative mode. In a tight loop there is no place where the timeout exception could occur. The same happened to Go until version 1.14 where the goroutines became fully preemptible. Although I don't know the details about how is that implemented. We could eventually do something similar in Crystal. Note that if you just use your implementation of |
|
So, what do we do about this? |
No description provided.