Liking cljdoc? Tell your friends :D

com.fulcrologic.fulcro.offline.durable-mutations

Support for durable mutations that can be automatically retried against a remote until a positive confirmation of success is received, or a specific kind of error indicates it cannot succeed.

You must configure your application in order to use this support. In particular, a durable storage for the mutations must be defined so that they can survive application restarts, power failures, etc. Your implementation of that storage will determine the overall reliability of these mutations. Additionally, you may define a custom optimistic tempid strategy that can do tempid remappings before ever talking to the server.

The mutations in a durable transaction must be:

  • Idempotent
  • Order-independent

This system asserts that the mutation in question will eventually run. However, it exposes the details of what is really going on at the mutation layer so that you can customize the behavior as needed.

IMPORTANT: The optimistic side of the mutation will run any time the mutation is tried. You can check (via durable-mutations/retry?) if this is a retry, and decide if there is anything to do in the UI.

Optimistic temporary ID remapping is supported, but requires that you define a TempidStrategy. This can be done by either pre-allocating a range from the server, or by allowing the client to use generated UUIDs (i.e. the UUID within the tempid itself). Your server must agree on this strategy for consistent operation.

It is a valid strategy to not resolve the tempids on the client, in which case your app state will have tempids on the items submitted until the real mutation completes. Tempid rewrites from the server are always applied, even if you had previously remapped them on the client.

Server-side implementations of durable mutations cannot have any meaningful return value other than :tempids since there is no guarantee when the real mutation will run.

There is a closure goog.define of BACKOFF_LIMIT_MS which defaults to 30000 (ms). This limits the maximum wait time between mutation retries and can be modified via compiler settings. See compiler docs.

NOTE: The backoff will cause mutations to appear somewhat slowly when network communication resumes. This is by design, and will prevent a flood of requests after a server outage. Caution: Setting this too low can cause blockage on retry logic when the network is down.

There is also a LOOP_TIMEOUT_MS (default 20ms). Any durable mutation transact submission, on average, appear to have this much latency. Setting it too low will cause the browser to waste a lot of CPU looking for trouble, setting it too high will annoy the user. DO NOT SET THIS TO 0.

Installation: See with-durable-mutations.

Usage: Use transact! from this ns, or add :com.fulcrologic.fulcro.offline.durable-mutations/durable? true to the options of your call to comp/transact!. Do not include follow-on reads in the transaction if using comp/transact!.

Support for durable mutations that can be automatically retried against a remote until a positive
confirmation of success is received, or a specific kind of error indicates it cannot succeed.

You must configure your application in order to use this support. In particular, a durable storage for the mutations
must be defined so that they can survive application restarts, power failures, etc.  Your implementation of that storage will determine
the overall reliability of these mutations. Additionally, you *may* define a custom optimistic tempid strategy that can do
tempid remappings before ever talking to the server.

The mutations in a durable transaction *must* be:

* Idempotent
* Order-independent

This system asserts that the mutation in question *will eventually* run. However, it exposes the details of
what is really going on at the mutation layer so that you can customize the behavior as needed.

IMPORTANT: The optimistic side of the mutation will run any time the mutation is tried. You can check (via
`durable-mutations/retry?`) if this is a retry, and decide if there is anything to do in the UI.

Optimistic temporary ID remapping is supported, but requires that you define a TempidStrategy.
This can be done by either pre-allocating a range from the server, or by allowing the client to use generated
UUIDs (i.e. the UUID within the tempid itself). *Your server must agree on this strategy for consistent operation*.

It is a valid strategy to *not* resolve the tempids on the client, in which case your app state will have tempids
on the items submitted until the real mutation completes. Tempid rewrites from the server are always applied, even
if you had previously remapped them on the client.

Server-side implementations of durable mutations cannot have any meaningful return value other than `:tempids` since
there is no guarantee when the real mutation will run.

There is a closure goog.define of BACKOFF_LIMIT_MS which defaults to 30000 (ms). This limits the maximum wait time between
mutation retries and can be modified via compiler settings. See compiler docs.

NOTE: The backoff will cause mutations to appear somewhat slowly when network communication resumes. This is by design,
and will prevent a flood of requests after a server outage. Caution: Setting this too low can cause blockage on retry
logic when the network is down.

There is also a LOOP_TIMEOUT_MS (default 20ms). Any durable mutation transact submission, on average, appear
to have this much latency. Setting it too low will cause the browser to waste a lot of CPU looking for trouble,
setting it too high will annoy the user. DO NOT SET THIS TO 0.

Installation: See `with-durable-mutations`.

Usage: Use `transact!` from this ns, or add `:com.fulcrologic.fulcro.offline.durable-mutations/durable? true` to the
options of your call to `comp/transact!`. Do not include follow-on reads in the transaction if using `comp/transact!`.
raw docstring

attemptclj/s

(attempt mutation-env)

Returns the attempt number of the mutation (using that mutation's env).

Returns the attempt number of the mutation (using that mutation's env).
sourceraw docstring

backoff-limit-msclj/s

source

BACKOFF_LIMIT_MScljs

source

cancel-mutation!clj/s

(cancel-mutation!
  {:com.fulcrologic.fulcro.algorithms.tx-processing/keys [options] :keys [app]})

Can be called from your mutation error-action (or result-action) to cancel any future attempts of the current instance of the current mutation.

Can be called from your mutation `error-action` (or `result-action`) to cancel any future attempts of the
current instance of the current mutation.
sourceraw docstring

current-mutation-storeclj/s

(current-mutation-store app)

Returns the current mutation store of the given Fulcro app

Returns the current mutation store of the given Fulcro app
sourceraw docstring

current-tempid-strategyclj/s

(current-tempid-strategy app)

Returns the current tempid strategy of the given Fulcro app

Returns the current tempid strategy of the given Fulcro app
sourceraw docstring

is-retry?clj/s

(is-retry? mutation-env)

Returns true if the mutation env represents an environment where the mutation is being retried. Returns false only on the initial submission of the mutation

Returns true if the mutation env represents an environment where the mutation is being retried. Returns false only
on the initial submission of the mutation
sourceraw docstring

loop-timeout-msclj/s

source

LOOP_TIMEOUT_MScljs

source

retry?clj/s

source

transact!clj/s

(transact! app-ish txn)
(transact! app-ish txn options)

Similar to comp/transact!, but the mutations in the transaction will first be written to a persistent store (on mutation per entry), and then each will be retried until they succeed or are explicitly cancelled. Transactions submitted with this function must be safe to run in parallel in any order, and any number of times (the semantic is that they will be retried until they succeed at least once).

WARNING: YOU MUST ENSURE ORDER DOES NOT MATTER ON A PER-MUTATION BASIS (order cannot be preserved without risking deadlock). This means [(f) (g) (h)] might run on the server as, for example, [(g)], two hours pass [(f)], 5 seconds pass [(h)].

Success is defined (by default) by your application's remote-error?. When there is no detected error the mutation will be removed from durable storage and your mutation's ok-action will be called. The mutation's error-action section can also decide that the attempt was "good enough" and explicitly cancel further retries with dm/cancel-mutation!.

Your mutation's action and result-action (or if you use them: error-action or ok-action) will be called on every attempt.

Your mutation's action body can use (dm/retry? env) to determine if this is the first attempt, and (dm/attempt env) to find out how many times it has been tried.

The result-action (or error-action) sections of your mutation can call (dm/cancel-mutation! env) to remove the durable mutation and stop retrying it. For example, you might decide that it is an application error that should be reported (e.g. for support purposes) via a different (possibly durable) mutation.

If the remote succeeds (remote-error? of your app reports false), then the mutation will automatically be removed from the persistent storage and your ok-action will be triggered.

The durability of these mutation across application restarts is dependent upon the implementation of the EDN store used with this facility.

NOTES:

  • The optimistic actions of the mutations in the transaction will fire every time the mutation is tried.
  • Operations submitted via this transact! are essentially considered to be legal to run or repeat at any time. This also means that the optimistic actions of the transaction are not guaranteed to run in any total order compared to any other transactions in Fulcro.
  • If you submit a transaction with more than one mutation it will actually be split into multiple transaction submissions (one mutation per transaction). This is to ensure that retries happen on a mutation granularity, since we cannot enforce full-stack transactional semantics.

WARNING: This function is exactly equivalent to comp/transact! unless you install support for it on your application. See with-durable-mutations.

Similar to comp/transact!, but the mutations in the transaction will first be written to a persistent store (on mutation
 per entry), and then each will be retried until they succeed or are explicitly cancelled. Transactions submitted with
 this function must be safe to run in parallel in any order, and any number of times (the semantic is that they
 will be retried until they succeed *at least once*).

 WARNING: YOU MUST ENSURE ORDER DOES NOT MATTER ON A PER-*MUTATION* BASIS (order cannot be preserved
 without risking deadlock). This means `[(f) (g) (h)]` might run on the server as, for example,
 `[(g)]`, two hours pass `[(f)]`, 5 seconds pass `[(h)]`.

 Success is defined (by default) by your application's `remote-error?`. When there is no detected error the mutation
 will be removed from durable storage and your mutation's `ok-action` will be called. The mutation's `error-action` section
 can also decide that the attempt was "good enough" and explicitly cancel further retries with `dm/cancel-mutation!`.

 Your mutation's `action` and `result-action` (or if you use them: `error-action` or `ok-action`) will be called
 *on every attempt*.

 Your mutation's `action` body can use `(dm/retry? env)` to determine if this is the first attempt, and `(dm/attempt env)`
 to find out how many times it has been tried.

 The `result-action` (or `error-action`) sections of your mutation can call `(dm/cancel-mutation! env)` to remove
 the durable mutation and stop retrying it. For example, you might decide that it is an application error that should
 be reported (e.g. for support purposes) via a different (possibly durable) mutation.

 If the remote succeeds (`remote-error?` of your app reports `false`), then the mutation will automatically be
 removed from the persistent storage and your `ok-action` will be triggered.

 The durability of these mutation across application restarts is dependent upon the implementation of the EDN store
 used with this facility.

 NOTES:

 * The optimistic actions of the mutations in the transaction will fire *every time the mutation is tried*.
 * Operations submitted via this `transact!` are essentially considered to be legal to run or repeat at any time.
   This also means that the optimistic actions of the transaction are *not* guaranteed to run in any total order
   compared to any other transactions in Fulcro.
 * If you submit a transaction with more than one mutation it will actually be split into multiple transaction
   submissions (one mutation per transaction).  This is to ensure that retries happen on a mutation granularity,
   since we cannot enforce full-stack transactional semantics.

WARNING: This function *is exactly equivalent to* `comp/transact!` unless you install support for it on your application.
See `with-durable-mutations`.
sourceraw docstring

with-durable-mutationsclj/s

(with-durable-mutations app mutation-store tempid-strategy)

Augments the given app with support for write-through mutations. RETURNS A NEW APP. You must use this like so:

(defonce app (-> (fulcro-app ...)
               (with-durable-mutations mutation-store tempid-strategy)))
  • mutation-store is an implementation of MutationStore.
  • tempid-strategy is an implementation of TempIdStrategy
Augments the given app with support for write-through mutations. RETURNS A NEW APP. You must use this like so:

```
(defonce app (-> (fulcro-app ...)
               (with-durable-mutations mutation-store tempid-strategy)))
```

* `mutation-store` is an implementation of MutationStore.
* `tempid-strategy` is an implementation of TempIdStrategy
sourceraw docstring

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

× close