Hacker News new | ask | show | jobs
by ackfoobar 702 days ago
Now handle the following that is painlessly solved by runtimes with structured concurrency:

If A failed, the whole function is failed, and we don't need B any more. To save resources we should cancel B. And vice versa, cancel A if B failed.

2 comments

    import github.com/carlmjohnson/flowmatic

    func whatever(ctx context.Context) {
        err := flowmatic.Race(ctx, taskA, taskB)
    }
Provide your definition of taskA and taskB, of course.

As I said in another message, this is not a particularly fruitful line of attack in either direction. All the languages in question are perfectly capable of abstractions.

I don't like that the return values of the tasks has to be communicated with side effects, but I'll concede that it's quite painless.

I guess I'm just still salty when someone commented (in another post a long time ago) that golang only has `go` (compared to `launch`, `async`, and `coroutineScope` in Kotlin) and is simpler.

> All the languages in question are perfectly capable of abstractions.

I don't think async functions in JS can be cancelled though.

"I don't like that the return values of the tasks has to be communicated with side effects, but I'll concede that it's quite painless."

Me neither, however, it is generally the most flexible approach and I can see why a library takes it. If you want to communicate it via the return, you also have to impose a restriction that the tasks all return the same type. I think it makes sense for a library to work this way because you can easily add this around the library call yourself, but it's more difficult to go the other way. (Not impossible, just more difficult.)

"I don't think async functions in JS can be cancelled though."

Poking around, it looks pretty hard.

That said, cancelling in generally is very difficult in imperative languages, so even as someone who finds async in JS quite distasteful I can't dock too many points. Go basically just reifies the JS solution into a standard community practice, which is definitely an improvement since you can largely rely on it being supported everywhere, but one could reasonably debate how good it is. It is occasionally a problem that if you want to cancel an ongoing computation you may have to have your code manually check a context every so often, because there's no "real" connection between a context and a goroutine.

If you’re fine with manually checking a standard interface to see if you should abort, JS’s answer is the AbortController. This is supported by features like the “fetch” function for making cancellable http requests.

https://developer.mozilla.org/en-US/docs/Web/API/AbortContro...

So, context.Cancel?