Fork me on GitHub
#fulcro
<
2023-08-19
>
Jakub Holý (HolyJak)07:08:29

Hello! Any tips for using fulcro-rad-datomic with Entity Specs? F.ex. I would like to ensure that it is impossible to delete a Product if any Order refers to it… 🙏

Jakub Holý (HolyJak)11:08:34

I guess a custom :datomic/transact in the Pathom env, which inspects the passed-in :tx-data and injects :db/ensure where appropriate would be the way to go...

tony.kay13:08:22

I would use save middleware

Jakub Holý (HolyJak)15:08:52

Would wrapping the default datomic save middleware help somehow? Or do you mean copy & modify that one?

tony.kay16:08:50

save middleware is just that: middleware. It is meant for you to add on layers to do whatever you need.

tony.kay16:08:02

One of my production middlewares, for example, does:

(def middleware
  (->
    (after-effects/wrap-synchronous-after-effects)          ; ONLY failure-tolerant synchronous effects, like cache refresh
    ;; Conflicts on atomicity, spec failures, etc. will throw exceptions and prevent after-effects. Atomicity problems
    ;; will retry the entire stack down to where the wrap-atomic-transaction started..
    (atomic/wrap-datomic-save {:datomic/transact taudit/transact})
    ;; NOTE: goes before the datomic save. Queues after effects that will run via a durable queue, but only if
    ;; the transaction succeeded
    (after-effects/wrap-durable-after-effects (fn [] after-effect-queue))
    ;; Resolve as late as possible, but early enough that the idempotent after-effects can know the remapping,
    (atomic/wrap-resolve-transaction-data)
    (wrap-schema-enforcement)
    (wrap-validations)
    (wrap-form-save-security)
    (wrap-speculative-application (comp gcr/garbage-collect-orphans esd/rewrite-form-delta refine/run-RAD-refinements))
    (wrap-retract-blank-strings)
    (om/wrap-enforce-ownership)
    (om/wrap-add-ownership)
    (atomic/wrap-atomic-transaction atomic/marker-txn dutils/optimistic-lock-exception?)))

tony.kay16:08:36

so, for example, the wrap-schema-enforcement relies on the speculative-application mw. The SA middleware uses with to pretend to do the transaction, and then pulls all of the entities affected from the after-db and puts the after-db, the intermediate tempids, and the pulled entities into env. Then things like schema enforcement can check that things are ok.

tony.kay16:08:53

Now, that said, save by default doesn’t “delete” anything. The delete middleware does if you’re using form-delete…so, for your case you’d augment delete-middleware to do the checks in question.

tony.kay16:08:18

In my case I actually do have save GC orphans, but that implementation requires a bit more annotation on the model

Jakub Holý (HolyJak)16:08:48

What I need to do is to include :db/ensure <my Datomic entity spec> in the transacted data. I don't see a clear way how middleware wrapping the delete middleware would do that...

tony.kay16:08:09

you’d customize your wrap-datomic-save, as I have above

Jakub Holý (HolyJak)16:08:40

Of course instead of using Entity Spec, I could do the check myself in a middleware...

tony.kay16:08:46

my wrap-datomic-save adds in a CAS to ensure atomic operation among multiple threads on read/write combined ops that don’t leverage transactor functions

Jakub Holý (HolyJak)16:08:29

Thank you. I will study this.

tony.kay16:08:33

So, for example, in mine I have wrap-atomic-transaction add a ::raw-txn to env, and then my customized wrap-datomic-save adds anything in ::raw-txn into the transact

tony.kay16:08:43

That way any part of the mw can augment the final transaction

Jakub Holý (HolyJak)16:08:10

Ah, that makes sense.

tony.kay16:08:14

We could add that pattern to the library if you want…not as the atomic support necessarily, but more as a way to allow mw elements to add things to the txn

❤️ 2
🙏 2
tony.kay16:08:38

just make it so the library looks for raw-txn in env and includes it

👍 2
tony.kay16:08:43

and add it to datomic options

tony.kay16:08:55

yeah…basically env is just a map…that’s why I wanted to show my stack, because I’m doing that pattern multiple times. The speculative application mw is particularly useful because it adds the “how things will look” to env so various different layers can use that.

😻 2
Jakub Holý (HolyJak)16:08:02

I'll try to make a PR later today

👍 2
tony.kay17:08:54

review complete…lets update the docstring according to my comment there, and perhaps add a helper

👀 2