Improve Task Chain
							parent
							
								
									2cb21dc102
								
							
						
					
					
						commit
						865e83cdae
					
				| 
						 | 
					@ -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 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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.
 | 
				
			||||||
		Loading…
	
		Reference in New Issue