proletarian

A durable job queuing and worker system for Clojure backed by PostgreSQL: https://github.com/msolli/proletarian
dominicm 2021-04-09T09:49:34.000300Z

Instead of running a global multi-method callback, would it be possible to run a provided function instead? That way I can create the function & context etc. as part of my system, and not need the ambiguous "context".

dominicm 2021-04-09T09:50:26.000400Z

It would also help with running multiple instances of the same application, but for different tables. e.g. in a multi-tenant application.

msolli 2021-04-09T10:57:19.003500Z

Hm, let me try to understand what you’re after. As a Queue Worker config option, you’d like to pass a function that will be called for all jobs in a given queue? This function then does its own dispatch internally (somehow – not any of Proletarian’s business) to handle the different job types?

dominicm 2021-04-09T10:57:57.003600Z

Yep. I might define it as a multi-method, or not. My choice.

dominicm 2021-04-09T10:58:14.003700Z

Another use case: Integration testing :).

msolli 2021-04-09T11:01:36.004600Z

It makes sense. Let me think about it. Good thing I added the -alpha to the version! 🙂

msolli 2021-04-09T11:02:10.005Z

Tell me more about the integration testing use case?

dominicm 2021-04-09T11:06:04.005100Z

Something like:

(deftest foo
  (let [called (atom false)
          worker (doto (worker/create-queue-worker (db) (fn [_job] (reset! called true))) worker/start!)
          handler (make-some-ring-handler (db)]
    (handler (mock/request :get "/foobar"))
    (is (= true @called))))
A slightly bad example, but I think you get the point :)

dominicm 2021-04-09T11:07:01.005200Z

To make that use-case simpler, it might be handy to allow creating some kind of "scope" to jobs, then you could parallelize your tests by generating a UUID as the scope. But then you need a way to carry around the scope, so ["some-uuid" db] instead of just db. Nvm, this is named queue support.

msolli 2021-04-09T11:10:05.006900Z

For that example to work, you’d need some wait mechanism so that the assert isn’t called before the worker has had time to poll the queue and run the handler function.

msolli 2021-04-09T11:10:29.007400Z

But the use case is valid, no doubt.

dominicm 2021-04-09T11:10:52.007800Z

Yeah, for sure. You'd probably end up using promises and timeouts 🙂

msolli 2021-04-09T11:14:32.009600Z

I haven’t really considered integration testing, to be honest. In my tests, I only check that the job gets written to the table. The handler functions have their own tests.

msolli 2021-04-09T11:16:09.010900Z

Having to wait for the worker to do its thing will make the tests (a lot) slower. But there are certainly situations where you’d want to test the whole thing.

dominicm 2021-04-09T11:21:59.011900Z

I could see some people wanting to test that too as a faster option, although there's potentially problems around if there's a worker listening to that eating it up before you can check it's there…

msolli 2021-04-09T11:37:47.013300Z

Yeah, I wouldn’t have a Queue Worker running in the test environment in that case.

msolli 2021-04-09T11:39:05.014400Z

Anyway, I’ll look into your suggestion for just passing a function as a universal job handler when I get the time. Thanks for the feedback!