Improve Task Chain

main
Bram van den Heuvel 2023-11-03 22:43:28 +01:00
parent 2cb21dc102
commit 865e83cdae
6 changed files with 45 additions and 49 deletions

View File

@ -31,30 +31,52 @@ type as a message to the Vault to update certain information.
-} -}
import Http import Http
import Internal.Api.Helpers as Helpers
import Internal.Tools.Context as Context exposing (Context) import Internal.Tools.Context as Context exposing (Context)
import Internal.Tools.Exceptions as X import Internal.Tools.Exceptions as X
import Task exposing (Task) import Task exposing (Task)
{-| The TaskChain is a piece in the long chain of tasks that need to be completed.
The type defines four variables:
- `err` value that may arise on an error
- `u` the update msg that should be returned
- `a` phantom type before executing the chain's context
- `b` phantom type after executing the chain's context
-}
type alias TaskChain err u a b = type alias TaskChain err u a b =
Context a -> Task (FailedChainPiece err u) (TaskChainPiece u a b) Context a -> Task (FailedChainPiece err u) (TaskChainPiece u a b)
{-| An IdemChain is a TaskChain that does not influence the chain's context
- `err` value that may arise on an error
- `u` the update msg that should be executed
- `a` phantom type before, during and after the chain's context
-}
type alias IdemChain err u a = type alias IdemChain err u a =
TaskChain err u a a TaskChain err u a a
{-| A CompleteChain is a complete snake that can be safely run and executed by
the Elm core.
-}
type alias CompleteChain u = type alias CompleteChain u =
TaskChain () u {} {} TaskChain () u {} {}
{-| A TaskChainPiece is a piece that updates the chain's context.
Once a chain is executed, the process will add the `messages` value to its list
of updates, and it will update its context according to the `contextChange`
function.
-}
type alias TaskChainPiece u a b = type alias TaskChainPiece u a b =
{ contextChange : Context a -> Context b { contextChange : Context a -> Context b
, messages : List u , messages : List u
} }
{-| A FailedChainPiece initiates an early breakdown of a chain. Unless caught,
this halts execution of the chain. The process will add the `messages` value to
its list of updates, and it will return the given `err` value for a direct
explanation of what went wrong.
-}
type alias FailedChainPiece err u = type alias FailedChainPiece err u =
{ error : err, messages : List u } { error : err, messages : List u }

View File

@ -37,46 +37,3 @@ ratelimited task =
_ -> _ ->
Task.fail e Task.fail e
) )
{-| Sometimes, you don't really care if something went wrong - you just want to try again.
This task will only return an error if it went wrong on the n'th attempt.
-}
retryTask : Int -> Task X.Error a -> Task X.Error a
retryTask n task =
if n <= 0 then
task
else
Task.onError
(\err ->
let
retry : Task X.Error a
retry =
retryTask (n - 1) task
in
case err of
X.InternetException (Http.BadUrl _) ->
Task.fail err
X.InternetException _ ->
retry
X.SDKException (X.ServerReturnsBadJSON _) ->
retry
X.SDKException _ ->
Task.fail err
X.ServerException _ ->
Task.fail err
X.ContextFailed _ ->
Task.fail err
X.UnsupportedSpecVersion ->
Task.fail err
)
task

View File

@ -16,7 +16,7 @@ import Internal.Values.Room as Internal
import Internal.Values.StateManager as StateManager import Internal.Values.StateManager as StateManager
import Internal.Values.Timeline as Timeline import Internal.Values.Timeline as Timeline
import Json.Encode as E import Json.Encode as E
import Task exposing (Task) import Task
{-| The `Room` type represents a Matrix Room. It contains context information {-| The `Room` type represents a Matrix Room. It contains context information

View File

@ -432,3 +432,8 @@ sync vault onResponse =
rooms : Vault -> List Room.Room rooms : Vault -> List Room.Room
rooms = rooms =
Snackbar.mapList Internal.getRooms Snackbar.mapList Internal.getRooms
settings : (Snackbar.Settings -> Snackbar.Settings) -> Vault -> Vault
settings =
Snackbar.updateSettings

View File

@ -33,10 +33,8 @@ interact with the API.
import Internal.Api.VaultUpdate as Api import Internal.Api.VaultUpdate as Api
import Internal.Invite exposing (RoomInvite) import Internal.Invite exposing (RoomInvite)
import Internal.Room exposing (Room) import Internal.Room exposing (Room)
import Internal.Tools.Exceptions as X
import Internal.Vault import Internal.Vault
import Json.Encode as E import Json.Encode as E
import Task exposing (Task)
{-| The Matrix API requires you to keep track of a lot of tokens, keys, values and more. {-| The Matrix API requires you to keep track of a lot of tokens, keys, values and more.
@ -58,6 +56,13 @@ translate those instructions to a `VaultUpdate` that you can feed to your `Vault
type alias VaultUpdate = type alias VaultUpdate =
Api.VaultUpdate Api.VaultUpdate
{-| After evaluating an update, the `Status` type tells you how the Vault.
-}
type Status
= Good
| Warning String ((VaultUpdate -> msg) -> Cmd msg)
| Break String ((VaultUpdate -> msg) -> Cmd msg)
{-| Create a new vault based on an access token. {-| Create a new vault based on an access token.
Keep in mind that access tokens might eventually be revoked or expire, Keep in mind that access tokens might eventually be revoked or expire,

7
src/refactors.md Normal file
View File

@ -0,0 +1,7 @@
# Design refactors to be made
The following refactors are to be made:
- We need an `Info` type that informs the user whether data exists, and if not, why it doesn't exist.
- We need a `Timeline` type that users can use to go through threads in the global room timeline.