Fork me on GitHub
#aleph
<
2018-09-20
>
pyr12:09:30

We ran into a surprising corner-case where if a deferred chain has a manifold from alia (from alia.manifold/execute) in the chain, the subsequent fns in the chain will be executed on the cassandra java-driver pool, not the manifold pool

pyr12:09:38

d/chain' avoids this behavior

pyr12:09:44

but it's a bit unclear right now how we could keep the benefits of d/chain while avoiding this behavior (which can quickly exhaust the small I/O callback pools used by cassandra-driver)

mpenet12:09:32

if I recall you can pass an :executor option to alia.manifold/execute to have the callback run in another pool

mpenet12:09:44

that could be a way to temporarly mitigate the issue

pyr12:09:01

I'll try that

pyr12:09:05

it still boggles me

pyr12:09:44

I can track that down to (d/on-realized (alia.manifold/execute ...) #(warn %) #(warn %)) as showing the callback running on the cassandra-driver netty threadpool

pyr12:09:13

I don't get how on-realized manages to schedule the callbacks on netty's threadpool

pyr12:09:51

(the result is a ListenableFuture which extends Future which manifold considers as a valid deferred)

mpenet12:09:46

I'd have to check how things work internally in manifold, I am not too familiar with it.

pyr12:09:46

but I'm not seeing where the execution is directed to the threadpool

mccraigmccraig12:09:29

huh, i'm surprised i've never run in to that problem

mccraigmccraig12:09:55

what made you notice it @pyr?

mpenet12:09:32

in alia we have the callback (guava future) run in execute currentThread, unless specified otherwise.

mpenet12:09:56

that's how I remember it at least (so from where execute was called from in short)

pyr12:09:08

@mccraigmccraig exhausting cassandra-driver's pool

pyr12:09:27

specifiying the executor in query opts obviously fixes the issue

pyr12:09:32

I'm still surprised

pyr12:09:53

since d/chain' doesn't expose the behavior

mccraigmccraig12:09:05

does the cassandra-driver pool throw when it's exhausted ?

mpenet12:09:01

Do you think alia should by default expose/use a callback threadpool to avoid these kind of odd cases?

pyr12:09:30

not necessarily

pyr12:09:43

the standard cassandra-driver threadpool is quite valid for I/O callbacks

mpenet12:09:46

If I recall I followed what java-driver does, not creating an additional pool for this and leaving it to the user

pyr12:09:55

and no cpu should happen there

mpenet12:09:56

but I ll revisit that

pyr12:09:03

so I think this is valid

pyr12:09:44

at some point the result is picked up as homomorphic to a deferred (makes sense) but the listenablefuture's callback pool is then used as the executor (doesn't yet make sense to me :-))

pyr12:09:55

I'll dig further and use :executor in the meantime

mpenet12:09:50

I get highlights/notifications on "alia" mentions, looking fwd to understanding what's up

pyr12:09:52

Ok, it seems to come down to this:

pyr12:09:15

alia creates a deferred w/o specifying an executor in alia.manifold/execute

pyr12:09:38

When d/success! or d/error! are called

pyr12:09:19

The corresponding deferred thus has no executor, which means that the callbacks will be executed on the calling thread, hence in this case on cassandra-driver's threadpool

mpenet12:09:54

oh right, so in theory just passing the :executor option value to deferred should do it, then the alia/execute calling thread would be the default and the user can overwrite that with that :executor option if needed

pyr12:09:03

ah wait no

pyr12:09:13

deferred with no args gets (ex/executor)

pyr12:09:16

my theory is wrong

pyr12:09:39

this is it though

pyr12:09:51

ex/executor yields nil in my case

pyr13:09:52

OK, so I can wrap alia.manifold/execute in a manifold.executor/with-executor and all is well

pyr13:09:57

sorry about the noise

mpenet13:09:15

no worries, good to know.

pyr13:09:25

(this keeps compute-bound in the manifold pool, and I/O in the cassandra-driver pool)