Fork me on GitHub
#pedestal
<
2018-02-13
>
hlship22:02:58

I'm trying to do something pretty tricky with pedestal routers and interceptors. Essentially, part of my application is routed based on stateful data that can change at any time.

hlship22:02:43

So I have a traditional (static) router, then an interceptor that builds (as needed) another router and adds it via io.pedestal.interceptor.chain/enqueue

hlship22:02:31

But I'm seeing that execution doesn't match my expectations.

hlship22:02:07

What I see is execution of the router, then execution of my interceptor, then execution of interceptors in a route matched by the router.

hlship22:02:11

That's a lot to process;

hlship22:02:31

BUT line 7 shows the router :enter step

hlship22:02:02

And that's where I'd expect the router to match paths and choose a route, and add that route's interceptors/handler to the execution chain.

hlship22:02:10

And those interceptors will put a :response into the context, which should trigger an unwind through the :leave events of all the interceptors so far.

hlship22:02:50

But then on line 9, we see app-router enter stage, which to mind mind shouldn't take place.

hlship22:02:21

Then on line 11 we start to see the interceptors chosen by the router start to execute.

hlship22:02:52

... and now I'm reading the code for chain and answering some of my own questions.

hlship22:02:30

So I think what happens is that the router and the app-dispatcher are enqueued initially. The router executes, matches a route, and adds its interceptors to the execution chain after the other app-dispatcher interceptor. app-dispatcher executes it's :enter stage, but does nothing THEN the route interceptors hits their :enter stage.

hlship22:02:00

So I think I can get what I want by moving some logic in app-dispatcher to a :leave step instead, and only if there's no :request already.

hlship22:02:40

Ah, I think I can stay in the :enter phase, but check to see if there's already a matched route.

hlship23:02:20

Yep, that's working nicely.