aleph

2018-09-20T12:02:55.000100Z

Hi!

2018-09-20T12:04:30.000100Z

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

2018-09-20T12:04:38.000100Z

d/chain' avoids this behavior

2018-09-20T12:05:44.000100Z

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)

mpenet 2018-09-20T12:12:32.000100Z

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

mpenet 2018-09-20T12:12:44.000100Z

that could be a way to temporarly mitigate the issue

2018-09-20T12:18:01.000100Z

I'll try that

2018-09-20T12:18:05.000100Z

it still boggles me

2018-09-20T12:18:44.000100Z

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

2018-09-20T12:19:13.000100Z

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

2018-09-20T12:19:51.000100Z

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

mpenet 2018-09-20T12:20:46.000100Z

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

2018-09-20T12:20:46.000200Z

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

mccraigmccraig 2018-09-20T12:21:29.000100Z

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

mccraigmccraig 2018-09-20T12:21:55.000100Z

what made you notice it @pyr?

mpenet 2018-09-20T12:22:32.000100Z

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

mpenet 2018-09-20T12:22:56.000100Z

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

2018-09-20T12:23:08.000100Z

@mccraigmccraig exhausting cassandra-driver's pool

2018-09-20T12:23:27.000100Z

specifiying the executor in query opts obviously fixes the issue

2018-09-20T12:23:32.000100Z

I'm still surprised

2018-09-20T12:23:53.000100Z

since d/chain' doesn't expose the behavior

mpenet 2018-09-20T12:24:04.000100Z

weird

mccraigmccraig 2018-09-20T12:24:05.000100Z

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

mpenet 2018-09-20T12:25:01.000100Z

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

2018-09-20T12:25:30.000100Z

not necessarily

2018-09-20T12:25:43.000100Z

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

mpenet 2018-09-20T12:25:46.000100Z

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

2018-09-20T12:25:55.000100Z

and no cpu should happen there

mpenet 2018-09-20T12:25:56.000100Z

but I ll revisit that

mpenet 2018-09-20T12:25:58.000100Z

yeah

mpenet 2018-09-20T12:26:00.000100Z

exactly

2018-09-20T12:26:03.000100Z

so I think this is valid

2018-09-20T12:26:44.000100Z

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 :-))

2018-09-20T12:26:55.000100Z

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

mpenet 2018-09-20T12:27:50.000100Z

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

2018-09-20T12:51:52.000100Z

Ok, it seems to come down to this:

2018-09-20T12:52:15.000200Z

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

2018-09-20T12:52:38.000100Z

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

2018-09-20T12:53:19.000100Z

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

mpenet 2018-09-20T12:54:54.000100Z

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

2018-09-20T12:55:03.000100Z

ah wait no

2018-09-20T12:55:13.000100Z

deferred with no args gets (ex/executor)

2018-09-20T12:55:16.000100Z

my theory is wrong

mpenet 2018-09-20T12:55:26.000200Z

hmm

2018-09-20T12:55:31.000100Z

sorry

2018-09-20T12:58:39.000100Z

this is it though

2018-09-20T12:58:51.000100Z

ex/executor yields nil in my case

2018-09-20T13:03:52.000100Z

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

2018-09-20T13:03:57.000100Z

sorry about the noise

mpenet 2018-09-20T13:04:15.000100Z

no worries, good to know.

2018-09-20T13:04:25.000200Z

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