-
Notifications
You must be signed in to change notification settings - Fork 22
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
handle backpressure #9
Comments
To do this, you definitely shouldn't use One possibility is to use the same model as core.async: As far as Sieppari is concerned, this would mean don't use |
Well, maybe I'm wrong about the first paragraph:
From https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool-- That is what I still believe the other two paragraphs are correct. Long-running tasks in the threadpool will be problematic. The other thing that I've noticed in the docs is that it's an unbounded queue, which is generally a bad idea. An easy way to know that your threads are overloaded is to have a fixed size queue. When it fills up, you can't add anything more, and that's a signal that you're overloaded. |
But here's the issue: (continue [c f] (future (f @c))) should be (continue [c f] (d/chain c f)) |
@ericnormand, at the moment Sieppari supports choosing your own async library - there's support for Manifold, core.async and Promesa in addition to using |
Yes, I agree. But what I was saying was that Sieppari uses However, I'm still researching it. It might not be as bad as I thought. |
So, I've done a bit more research: Currently, on the develop branch, Sieppari creates 4 threads per async request, with no bounds, using You probably already know this, but just so we're all on the same page, I'll bring it up. The whole point of asynchronous operation is to not require a thread per request. Asynchrony allows you to handle many requests with a relatively small, finite number of threads. |
Right, the async implementation is even more broken than I realized. W.r.t to using
I don't think it is in Sieppari's scope to create yet another async computation library, so maybe the right thing to do is to remove the |
Both Protocols and MultiMethods are mutable global state and should not be used here. I propose a separate creation/compilation stage, where you explicitely define what kind of runner want to be created. Things to configure, at least:
default the support on JVM only to could look something like this (with fn->enter mapping and syntax ideas from #15): (def runner1 (s/runner)) ;; defaults
(def runner2 (s/runner {:dynamic-queue false, :chain sieppari.core_async/chain}))
(defn async-interceptor [k f n]
#(a/go (update % k (fnil f 0) n)))
(-> (s/context runner2)
(s/enqueue [(async-interceptor :n + 10) (async-interceptor :n * 2)])
(s/run)
(s/await)
:n)
; 20 |
I really like the idea of a compilation stage, but it doesn't work with the
interceptor model of computation. Interceptors allow you to add things to
the interceptor queue within the interceptors. I've often thought this was
a mistake. As far as I can tell, that was built into Pedestal as a clever
way to do routing. A statically known interceptor chain which can be
compiled and otherwise optimized would be much faster and easier to
understand. It might also have exploitable algebraic properties, like being
a monoid.
That said, I think the implementation would get hairy. There's quite a lot
of logic about what to do next. It's not quite as simple as having a
success callback and an error callback.
…On Sun, Sep 22, 2019 at 2:30 PM Tommi Reiman ***@***.***> wrote:
Both Protocols and MultiMethods are mutable global state and should not be
used here. I propose a separate creation/compilation stage, where you
explicitely define what kind of runner want to be created. Things to
configure, at least:
- support for dynamic queues -> static chains can be optimized for
stellar perf. e.g. a chain of just :enters with Manifold could be
evaluated with just d/chain'. Only enters with CompletionStage would
be just a chain of java functions, e.g. "java-fast".
- which async-libraries are supported, either just one or a set of
those
- default the support on JVM only to
java.util.concurrent.CompletionStage. Both pohjavirta
<https://github.com/metosin/pohjavirta> and porsas
<https://github.com/metosin/porsas> lean on these and you can use libs
like promesa <https://github.com/funcool/promesa> and auspex
<https://github.com/mpenet/auspex> with it.
could look something like this (with fn->enter mapping and syntax ideas
from #15 <#15>):
(def runner1 (s/runner)) ;; defaults
(def runner2 (s/runner {:dynamic-queue false, :chain sieppari.core_async/chain}))
(defn async-interceptor [k f n]
#(a/go (update % k (fnil f 0) n)))
(-> (s/context runner2)
(s/enqueue [(async-interceptor :n + 10) (async-interceptor :n * 2)])
(s/run)
(s/await)
:n); 20
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#9?email_source=notifications&email_token=AAA4LTG7X4L7H3EOTJWGEFDQK7BVTA5CNFSM4FS5QNU2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7JNITI#issuecomment-533910605>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAA4LTCN7KBVV6IRIVK365LQK7BVTANCNFSM4FS5QNUQ>
.
|
This is terrible. |
How to solve backpressure with Sieppari. Related:
The text was updated successfully, but these errors were encountered: