fulcro

Book: http://book.fulcrologic.com, Community Resources: https://fulcro-community.github.io/, RAD book at http://book.fulcrologic.com/RAD.html
zhuxun2 2021-04-08T15:59:59.429600Z

Is there any documentation about ::txn/submission-queue, ::txn/active-queue, and ::txn/send-queues? The source code in the txn namespace is a bit hard to follow

tony.kay 2021-04-08T16:21:23.430200Z

If you check out the source and use deps to make that what you’re using for your code, then you can decorate the tx processing code with calls to https://github.com/fulcrologic/fulcro/blob/develop/src/main/com/fulcrologic/fulcro/algorithms/tx_processing_debug.cljc tx-status, which will dump whats in the various queues.

tony.kay 2021-04-08T16:21:54.430600Z

(`tap>` is your better friend here, these days)

tony.kay 2021-04-08T16:27:19.430800Z

This section of the book mentions what all is going on in there: https://book.fulcrologic.com/#_the_transaction_processing_system

1🙏
2021-04-08T17:28:55.431Z

A while ago I was playing around with having the tx layer combine transactions into one network call. I left some cursory notes from my code dive here: https://github.com/dvingo/fulcro/blob/f0df8f8cf144e5c544af5a038cf6f5fca8b406b2/src/main/com/fulcrologic/fulcro/algorithms/tx-processing-readme.adoc#dans-notes or view the text bc I wasn't careful with formatting (the section "Dan's notes") : https://raw.githubusercontent.com/dvingo/fulcro/f0df8f8cf144e5c544af5a038cf6f5fca8b406b2/src/main/com/fulcrologic/fulcro/algorithms/tx-processing-readme.adoc (warning, very rough - typos etc, was meant for me to organize my thoughts 🙂 )

1🤘
zhuxun2 2021-04-08T21:19:47.432Z

Ok, I found the answer. I'm writing it down for my own future reference. First, be clear that a transaction could have multiple elements (i.e., first-level children of the ast, each correspond to a defmutation), and an element can have multiple remotes, and finally, two different elements can (and likely) have the same remote. When processing the ::send-queue, Fulcro combines sends from multiple elements when they have the same remote. This means that we need to demultiplex the combined remote response. Fulcro does the demultiplexing in the txn/combine-sends function, where it says

(doseq [{::keys [ast result-handler]} to-send]
  (let [new-body (if (map? body)
                    (select-keys body (top-keys ast))
                    body)
        result   (assoc combined-result :body new-body)]
    ...
    (result-handler result)))
There you see that if the body is not a map, each element's (i.e. defmutation's) result-action will receive a whole copy of the body. However, if the body is a map, each element's result-action will receive only a subset of the whole body, containing only the keys that it queried for (the first-level children's keys).

1❤️
zhuxun2 2021-04-08T21:26:39.432200Z

And global-error-action is invoked at the default result-action (i.e., m/default-result-action!) where it says:

(-> env
    (update-errors-on-ui-component! ::mutation-error)
    (rewrite-tempids!)
    (integrate-mutation-return-value!)
    (trigger-global-error-action!)
    (dispatch-ok-error-actions!))
And this result-action is the result-handler referred in the txn/combine-sends.

zhuxun2 2021-04-08T21:33:58.432800Z

@tony.kay I feel even though this way of multiplexing makes sense (it gives a valid pathom query that can be directly fed into a Pathom parser), it doesn't fit Fulcro exactly. For example, you mentioned yourself that "nodes with the same ID" cannot be handled at the moment. Maybe the multiplexing/demultiplexing can be handled using a Fulcro-specific protocol?

tony.kay 2021-04-08T23:39:53.433300Z

The issue, at its core, is this: [(f) (g) (h)], where those three mutations all have different remotes. Each of them has a result section which is going to be triggered from a separate network response. If those mutations all went to the same remote, then you can do some combining. The general problem is much harder than the common one.

tony.kay 2021-04-08T23:40:43.433500Z

So it isn’t multiplexing…each mutation has a singular existence, and can even talk to multiple remotes. Each network request needs a separate tracking node.

tony.kay 2021-04-08T23:41:18.433700Z

The combining logic that is currently present can only recombine nodes from a single transaction that all share the same desired remote.

tony.kay 2021-04-08T23:43:39.433900Z

In terms of the code you’re referncing, it is distributing result to mutations. The map in question will be keyed by dispatch symbol {'f result-map 'g result-map …}, and the top-keys of the AST of [(f)] will be 'f

tony.kay 2021-04-08T23:44:43.434100Z

so, it is possible there is some kind of bug in the transaction logic, but I kind of doubt it…you may have changed the shape of the result from the server in an incorrect way due to it being an error

tony.kay 2021-04-08T23:45:22.434300Z

Returning an error from the server that should be targeted at a mutation requires that you return a map keyed by the mutation name, which is the exact shape normal mutations return.

tony.kay 2021-04-08T23:46:32.434500Z

i.e. The result of the mutation is nothing if it failed…you should not expect its result to be anything at all, which is why you get the entire env, which I think has other keys on it around the result so you can see the raw result.