akira/exq

Order of middleware execution

vovayartsev opened this issue · 1 comments

Tested this in exq v0.15.0:

config :exq,
  middleware: [
    Exq.Middleware.Stats,
    Exq.Middleware.Job,
    Exq.Middleware.Manager,
    MyApp.One,
    MyApp.Two
  ]

It appeared that the order of execution of these middleware modules in the success scenario was:

before_work: ONE
before_work: TWO
    <worker module's perform>
after_processed_work: ONE
after_processed_work: TWO

and similar for after_failed_work callbacks in the worker's crash scenario.

Expected behaviour

I thought that after_*_work functions should be called in a reversed order so that middleware modules "wrap" each other like this:

before_work: ONE
  before_work: TWO
    <worker module's perform>
  after_processed_work: TWO
after_processed_work: ONE

This way after_*_work callback of a middleware has a chance to cleanup any side-effects it introduced in before_work (e.g. I'm hacking on pipeline.assigns.worker_module and pipeline.assigns.job.args).

At this point, it would be hard to change the existing behavior without breaking some existing code. We could probably consider a compile-time flag if there are some good use cases that can't work based on the current ordering logic.