Liking cljdoc? Tell your friends :D

com.fulcrologic.fulcro.algorithms.tx-processing.synchronous-tx-processing

A transaction processing system that does as much synchronously as possible, and removes various elements of complexity that were inherited from Fulcro 2 in the standard tx processing.

See with-synchronous-transactions for how to install it.

This tx processing system does as much work synchronously as possible, though it does try to preserve the call-order semantics of the standard transaction processing: That is to say that if the optimistic action of a transaction submits a new transaction then that new submission will run after the current already-in-progress transaction has finished processing:

(defmutation g [_]
  (action [{:keys [state]}] (swap! state ...))
  (ok-action [{:keys [app]}] (transact! app [(h)]))
  (remote [_] true))

(defmutation f [_]
  (action [{:keys [state app]}]
    (swap! state ...)
    (transact! app [(g)])))

...
(dom/a {:onClick (fn []
                   (transact! this [(f {:x 1})])
                   (transact! this [(f {:x 2})])
                   (transact! this [(f {:x 3})])))

A user clicking the above link with std processing could see any of the following:

f,f,f,g,g,g,h,h,h
f,f,f,g,h,g,g,h,h
f,f,f,g,g,h,g,h,h
etc.

In sync tx processing, you would more likely see:

f,g,f,g,f,g,h,h,h

because there is no guarantee in Fulcro's semantics about the space between two calls to transact!. If your application relies on the groupings that happen with the standard tx processing (submissions while holding a thread go into the queue first) then your application may break when you switch to sync processing.

Note that transactions are treated as atomically as possible. So, if you want a specific grouping you should submit it as a single tx:

(transact! [(f) (g)])
(transact! [(f) (g)])

is guaranteed to do f,g,f,g, and never f,f,g,g, though it is still possible to see f,g,h,f,g,h.

This sync transaction processing system allows you to push most (if not all) behavior of even nested transactions into a single synchronous operation. This will lead to significant improvements in the snappiness of the UI for optimistic operation and should also reduce over-rendering (multiple calls to render due to multiple async operations).

If your remote is mocked as a synchronous operation, then you can also leverage this tx processor to enable completely synchronous testing of your headless Fulcro application.

WARNING: This tx processing system does not support:

  • ptransact!: Pessimistic transactions are a legacy feature of Fulcro 2 that is no longer necessary. New applications should not use the feature, and this sync tx processing system does not support it. The call will succeed, but will behave as a normal transact!.
A transaction processing system that does as much synchronously as possible, and removes various elements
of complexity that were inherited from Fulcro 2 in the standard tx processing.

See `with-synchronous-transactions` for how to install it.

This tx processing system does as much work synchronously as possible, though it does try to preserve the
call-order *semantics* of the standard transaction processing: That is to say that if the optimistic action
of a transaction submits a new transaction then that new submission will run *after* the current already-in-progress
transaction has finished processing:

```
(defmutation g [_]
  (action [{:keys [state]}] (swap! state ...))
  (ok-action [{:keys [app]}] (transact! app [(h)]))
  (remote [_] true))

(defmutation f [_]
  (action [{:keys [state app]}]
    (swap! state ...)
    (transact! app [(g)])))

...
(dom/a {:onClick (fn []
                   (transact! this [(f {:x 1})])
                   (transact! this [(f {:x 2})])
                   (transact! this [(f {:x 3})])))
```

A user clicking the above link with std processing could see any of the following:

```
f,f,f,g,g,g,h,h,h
f,f,f,g,h,g,g,h,h
f,f,f,g,g,h,g,h,h
etc.
```

In sync tx processing, you would more likely see:

```
f,g,f,g,f,g,h,h,h
```

because there is *no guarantee* in Fulcro's semantics about the space between two calls to `transact!`. If your
application relies on the groupings that happen with the standard tx processing (submissions while holding a thread
go into the queue first) then your application may break when you switch to sync processing.

Note that transactions *are* treated as atomically as possible. So, if you want a specific grouping you should submit
it as a single tx:

```
(transact! [(f) (g)])
(transact! [(f) (g)])
```

is guaranteed to do `f,g,f,g`, and never `f,f,g,g`, though it is still possible to see `f,g,h,f,g,h`.

This sync transaction processing system allows you to push most (if not all) behavior of even nested transactions into a single
synchronous operation. This will lead to significant improvements in the snappiness of the UI for optimistic operation
and should also reduce over-rendering (multiple calls to render due to multiple async operations).

If your remote is mocked as a synchronous operation, then you can also leverage this tx processor to enable
completely synchronous testing of your headless Fulcro application.

WARNING: This tx processing system does *not* support:

* `ptransact!`: Pessimistic transactions are a legacy feature of Fulcro 2 that is no longer necessary. New
applications should not use the feature, and this sync tx processing system does not support it. The call
will succeed, but will behave as a normal `transact!`.
raw docstring

abort!clj/s

[app abort-id]

Implementation of abort when using this tx processing

[app abort-id]

Implementation of abort when using this tx processing
sourceraw docstring

activate-submissions!clj/s

(activate-submissions! app)

Activate all of the transactions that have been submitted since the last activation. After the items are activated a single processing step will run for the active queue.

Activation can be blocked by the tx-node options for things like waiting for the next render frame.

Activate all of the transactions that have been submitted since the last activation. After the items are activated
a single processing step will run for the active queue.

Activation can be blocked by the tx-node options for things like waiting for the next render frame.
sourceraw docstring

active-queueclj/s

(active-queue app)
source

add-send!clj/s

(add-send! app
           {:com.fulcrologic.fulcro.algorithms.tx-processing/keys [id options]
            :as tx-node}
           ele-idx
           remote)

Generate a new send node and add it to the appropriate send queue.

Generate a new send node and add it to the appropriate send queue.
sourceraw docstring

apps-in-txclj/s

source

available-work?clj/s

(available-work? app)

Returns true if the submission queue has work on it that can proceed without any restrictions.

Returns true if the submission queue has work on it that can proceed without any restrictions.
sourceraw docstring

dispatch-result!clj/s

(dispatch-result! app
                  tx-node
                  {:com.fulcrologic.fulcro.algorithms.tx-processing/keys
                     [results dispatch desired-ast-nodes transmitted-ast-nodes
                      original-ast-node]
                   :as tx-element}
                  remote)

Figure out the dispatch routine to trigger for the given network result. If it exists, send the result to it.

Returns the tx-element with the remote marked complete.

Figure out the dispatch routine to trigger for the given network result.  If it exists, send the result
to it.

Returns the tx-element with the remote marked complete.
sourceraw docstring

distribute-element-results!clj/s

(distribute-element-results!
  app
  tx-node
  {:keys [:com.fulcrologic.fulcro.algorithms.tx-processing/results
          :com.fulcrologic.fulcro.algorithms.tx-processing/complete?]
   :as tx-element})

Distribute results and mark the remotes for those elements as complete.

Distribute results and mark the remotes for those elements as complete.
sourceraw docstring

distribute-results!clj/s

(distribute-results! app txn-id ele-idx)

Side-effects against the app state to distribute the result for txn-id element at ele-idx. This will call the result handler and mark that remote as complete.

Side-effects against the app state to distribute the result for txn-id element at ele-idx. This will call the result
handler and mark that remote as complete.
sourceraw docstring

do-post-processing!clj/s

(do-post-processing! app)

Runs the queued post processing steps until the post-processing queue is empty.

Runs the queued post processing steps until the post-processing queue is empty.
sourceraw docstring

in-transactionclj/smacro

(in-transaction app-sym & body)
source

in-transaction?clj/s

(in-transaction? {:com.fulcrologic.fulcro.application/keys [id] :as app})

Returns true if the current thread is in the midst of running the optimistic actions of a new transaction.

Returns true if the current thread is in the midst of running the optimistic actions of a new transaction.
sourceraw docstring

post-processing-stepsclj/s

(post-processing-steps app)
source

post-processing?clj/s

(post-processing? app)

Is there post processing to do?

Is there post processing to do?
sourceraw docstring

process-queue!clj/s

(process-queue!
  {:com.fulcrologic.fulcro.application/keys [state-atom runtime-atom] :as app})

Run through the active queue and do a processing step.

Run through the active queue and do a processing step.
sourceraw docstring

process-send-queues!clj/s

(process-send-queues! app)

Process the send queues against the remotes, which will cause idle remotes with queued work to issue network requests.

Process the send queues against the remotes, which will cause idle remotes with queued work to issue network requests.
sourceraw docstring

process-tx-node!clj/s

(process-tx-node! app
                  {:keys
                     [:com.fulcrologic.fulcro.algorithms.tx-processing/options]
                   :as tx-node})
source

queue-element-sends!clj/s

(queue-element-sends! app
                      tx-node
                      {:com.fulcrologic.fulcro.algorithms.tx-processing/keys
                         [idx dispatch started?]})

Queue all (unqueued) remote actions for the given element. Returns the (possibly updated) node.

Queue all (unqueued) remote actions for the given element.  Returns the (possibly updated) node.
sourceraw docstring

queue-sends!clj/s

(queue-sends! app
              {:keys [:com.fulcrologic.fulcro.algorithms.tx-processing/options
                      :com.fulcrologic.fulcro.algorithms.tx-processing/elements]
               :as tx-node})

Finds any item(s) on the given node that are ready to be placed on the network queues and adds them. Non-optimistic multi-element nodes will only queue one remote operation at a time.

Finds any item(s) on the given node that are ready to be placed on the network queues and adds them. Non-optimistic
multi-element nodes will only queue one remote operation at a time.
sourceraw docstring

record-result!clj/s

(record-result! app txn-id ele-idx remote result)
(record-result! app txn-id ele-idx remote result result-key)

Deal with a network result on the given txn/element.

Deal with a network result on the given txn/element.
sourceraw docstring

release-post-render-tasks!clj/s

(release-post-render-tasks! app)

Should be called after the application renders to ensure that transactions blocked until the next render become unblocked. Schedules an activation.

Should be called after the application renders to ensure that transactions blocked until the next render become
unblocked. Schedules an activation.
sourceraw docstring

remove-send!clj/s

(remove-send! app remote txn-id ele-idx)

Removes the send node (if present) from the send queue on the given remote.

Removes the send node (if present) from the send queue on the given remote.
sourceraw docstring

reset-active-queue!clj/s

(reset-active-queue! app v)
source

reset-post-processing-steps!clj/s

(reset-post-processing-steps! app v)
source

reset-send-queue!clj/s

(reset-send-queue! app remote v)
source

reset-submission-queue!clj/s

(reset-submission-queue! app v)
source

run-after!clj/s

(run-after! app f)

Add f as a function that will run after the current transaction has been fully processed.

Add `f` as a function that will run after the current transaction has been fully processed.
sourceraw docstring

run-all-immediate-work!clj/s

(run-all-immediate-work! app)

Runs the submission queue. If the submission queue's optimistic actions submit more to the submission queue, then those are processed as well until the submission queue remains empty. This can start network requests.

Runs the submission queue. If the submission queue's optimistic actions submit more to the submission queue, then those
are processed as well until the submission queue remains empty. This can start network requests.
sourceraw docstring

run-queue!clj/s

(run-queue! app {:keys [component synchronous?] :as options})
source

send-queueclj/s

(send-queue app remote)
source

submission-queueclj/s

(submission-queue app)
source

submit-sync-tx!clj/s

(submit-sync-tx! app tx)
(submit-sync-tx! {:com.fulcrologic.fulcro.application/keys [runtime-atom]
                  :as app}
                 tx
                 options)
source

swap-active-queue!clj/s

(swap-active-queue! app & args)
source

swap-post-processing-steps!clj/s

(swap-post-processing-steps! app & args)
source

swap-send-queue!clj/s

(swap-send-queue! app remote & args)
source

swap-submission-queue!clj/s

(swap-submission-queue! app & args)
source

sync-tx!clj/s

(sync-tx! & args)
source

top-level?clj/s

(top-level? {:com.fulcrologic.fulcro.application/keys [id]})

Returns true if the current thread is running non-nested transaction processing code.

Returns true if the current thread is running non-nested transaction processing code.
sourceraw docstring

with-synchronous-transactionsclj/s

(with-synchronous-transactions app)

Installs synchronous transaction processing on a fulcro application.

(defonce app (stx/with-synchronous-transactions
               (app/fulcro-app {...})))

This plug-in attempts to do as much work as possible synchronously, including the processing of "remotes" that can behave synchronously. This processing system preserves transactional ordering semantics for nested submissions, but cannot guarantee that the overall sequence of operations will exactly match what you'd see if using the standard tx processing.

The options map you can pass to transact! supports most of the same things as the standard tx processing, with the significant exception of :optimistic? false (pessimistic transactions). It also always assumes synchronous operation, thought the synchronous? option (if used) does imply that only the current component should be refreshed in the UI.

  • :ref - ident. The component ident to include in the transaction env.
  • :component - React element. The instance of the component that should appear in the transaction env.
  • :synchronous? - When true, causes the rendering to only refresh the calling component (if possible), since the implication is for fast-as-possible refresh semantics, even though this tx processing is already sync.
  • :refresh - A hint. Vector containing idents (of components) and keywords (of props). Things that have changed and should be re-rendered on screen. Only necessary when the underlying rendering algorithm won't auto-detect, such as when UI is derived from the state of other components or outside of the directly queried props. Interpretation depends on the renderer selected: The ident-optimized render treats these as "extras".
  • :only-refresh - A hint. Vector of idents/keywords. If the underlying configured rendering algorithm supports it: The components using these are the only things that will be refreshed in the UI, and they may be refreshed immediately on transact!. This can be used to avoid the overhead of looking for stale data when you know exactly what you want to refresh on screen as an extra optimization. Idents are not checked against queries.

If the options include :ref (which comp/transact! sets), then it will be auto-included on the :refresh list.

Returns the transaction ID of the submitted transaction.

Installs synchronous transaction processing on a fulcro application.

```
(defonce app (stx/with-synchronous-transactions
               (app/fulcro-app {...})))
```

This plug-in attempts to do as much work as possible synchronously, including the processing of "remotes" that
can behave synchronously. This processing system
preserves transactional ordering semantics for nested submissions, but cannot guarantee that the overall sequence of
operations will exactly match what you'd see if using the standard tx processing.

The options map you can pass to `transact!` supports most of the same things as the standard tx processing, with the significant exception of
`:optimistic? false` (pessimistic transactions). It also *always* assumes synchronous operation, thought the
`synchronous?` option (if used) does imply that only the current component should be refreshed in the UI.

- `:ref` - ident. The component ident to include in the transaction env.
- `:component` - React element. The instance of the component that should appear in the transaction env.
- `:synchronous?` - When true, causes the rendering to only refresh the calling component (if possible), since the implication
is for fast-as-possible refresh semantics, even though this tx processing is already sync.
- `:refresh` - A hint. Vector containing idents (of components) and keywords (of props). Things that have changed and should be re-rendered
  on screen. Only necessary when the underlying rendering algorithm won't auto-detect, such as when UI is derived from the
  state of other components or outside of the directly queried props. Interpretation depends on the renderer selected:
  The ident-optimized render treats these as "extras".
- `:only-refresh` - A hint. Vector of idents/keywords.  If the underlying configured rendering algorithm supports it: The
  components using these are the *only* things that will be refreshed in the UI, and they may be refreshed immediately on
  `transact!`. This can be used to avoid the overhead of looking for stale data when you know exactly what
  you want to refresh on screen as an extra optimization. Idents are *not* checked against queries.

If the `options` include `:ref` (which comp/transact! sets), then it will be auto-included on the `:refresh` list.

Returns the transaction ID of the submitted transaction.
sourceraw docstring

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close