-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
streaming asynchronous exception #104
Comments
@tim2CF: My first instinct when I see an unkillable thread is that something is blocked on an unsafe FFI call |
Probably gRPC C code is causing this right? In some cases I can replace |
Yeah, I suspect an FFI call in the binding to the The second most common reason for this is finalization logic that inappropriately masks exceptions, leading to Haskell code that blocks and is uninterruptible. |
Thanks @Gabriel439 ! There my gRPC stream handler throws exception, just because I have no idea how to terminate subscription from handler when handler receives some corrupted or unexpected data. If there is nice way without exceptions, I would like to use it |
Thanks! Any thoughts about proper termination of gRPC subscription from inside of the handler?
So I have no idea how I do terminate stream from the handler if it gets some corrupted data |
@tim2CF: I'm not sure, but have you tried manually terminating by not executing any more If you need something a bit more high-level you could do something like this: https://hackage.haskell.org/package/break-1.0.2/docs/Control-Break.html |
If I'm not calling recursively stream handler - subscription will just terminate? And catching if from outside in level of subscription It works, so seems like not an issue at all, I just was confused a bit because I'm not using exceptions in Haskell in everyday basis. But thanks for reply! |
@tim2CF: My understanding is that subscription will terminate when the callback you supply to That said, I think you should be able to safely throw an exception inside of the handler. If that causes issues then we can always look into that |
Thanks! |
@tim2CF: You're welcome! 🙂 |
Hi again, @Gabriel439! Is it possible that gRPC subscription client is still non-cancellable from the client side with As I remember, you was talking about cancellation from the server side, but here is example how I'm trying to cancel client async subscription from client side as well. I'm using latest versions or your gRPC package with previous fix already included, but for some reason it's still not working. |
In my examples I'm using my own I don't think this difference can cause problems, I think it will work the same way with original function from Async package. |
As additional info I can say that seems like process spawned like this is not cancellable. Can it be true? -- spawning grpc subscription in new async thread
pid <- async $ withGRPCClient config $ \client -> do
blablabla
-- this seems not working until async thread is exited
cancel pid |
I did compiled grpc-haskell with debug flag and found that subscription thread is hanging after log
and then it's hanging in
and then finally shutting down/cancelling (without delay)
I hope this can help you to understand what's going on there, and why process is not getting cancelled immediately (I still thinking it can be fault on my side where I'm using gRPC library) @Gabriel439 |
A took a look to gRPC-haskell source code a bit, and according my issue with client long subscription cancellation and logs produced in debug mode, it might be because of this
What do you think? |
@tim2CF: Yes, generally use of |
Cool, thanks Gabriel! Sorry for the spam. This library seems the only one complete gRPC library for Haskell and I had no idea how to fix the issue. |
fwiw, I added the |
@cocreature: Actually, it's not clear to me why the |
This PR moves the non-Haskell specific code generator utilities from `DotProto.Generate` to `DotProto.Internal`. I've gone through the `DotProto.Generate` module and made stylistic improvements---the changes are largely cosmetic. This refactor also paves the way for a Purescript code generator feature that I'm hacking on. Major changes: - Pass args struct to `compileDotProtoFile` runner - Enforce that `Path` is nonempty using `List.NonEmpty`. This removes a case from `CompileError` - Nice combinators for writing `importDecl_` statements (see `defaultImports`) - Pass file name to parsec; report file name in parser errors - Make `DotProtoServiceRPC` args a separate type - Clarify codegen steps using `foldMapM` and `foldMapOfM`. This might also improve efficiency by causing separate traversal steps (e.g. map -> sequence -> mconcat) to be done in a single pass, depending on what ghc was doing with the original code... - Improve readability and organisation of large codegen functions The version has been updated to `0.3.0.1` to reflect minor changes in types and dependencies.
Hi! I'm using
async
package to manage my threads. In many placesrace
function is very handy. For example:res <- race receiveLongServerStream executeSomethingShort
where
receiveLongServerStream
is client action which receives some events from gRPC server, any amount of events, basically it's infinite threadand
executeSomethingShort
is something short-living process which should normally return value first, thenrace
function should cancelreceiveLongServerStream
and returnres
which is supposed to be Right there, becauseexecuteSomethingShort
returned value first.But for some reason all expression is blocked, probably because
race
can't cancelreceiveLongServerStream
for some reason. Here is docs for cancel function if it can helphttps://hackage.haskell.org/package/async-2.2.2/docs/Control-Concurrent-Async.html#v:cancel
I just want to know how I can deal with it. Because this behaviour is causing deadlocks.
The text was updated successfully, but these errors were encountered: