Commit 613a0217 authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

[loader] useCacheWithAPI loader with errorHandler

parent fe2bbca3
...@@ -7,14 +7,13 @@ module Gargantext.Components.NgramsTable ...@@ -7,14 +7,13 @@ module Gargantext.Components.NgramsTable
import Gargantext.Prelude import Gargantext.Prelude
import Data.Array as A import Data.Array as A
import Data.Either (Either(..)) import Data.Either (Either)
import Data.FunctorWithIndex (mapWithIndex) import Data.FunctorWithIndex (mapWithIndex)
import Data.Lens (Lens', to, (%~), (.~), (^.), (^?), view) import Data.Lens (Lens', to, (%~), (.~), (^.), (^?), view)
import Data.Lens.At (at) import Data.Lens.At (at)
import Data.Lens.Common (_Just) import Data.Lens.Common (_Just)
import Data.Lens.Fold (folded) import Data.Lens.Fold (folded)
import Data.Lens.Index (ix) import Data.Lens.Index (ix)
import Data.Lens.Record (prop)
import Data.Map (Map) import Data.Map (Map)
import Data.Map as Map import Data.Map as Map
import Data.Maybe (Maybe(..), fromMaybe, isNothing, maybe) import Data.Maybe (Maybe(..), fromMaybe, isNothing, maybe)
...@@ -23,11 +22,15 @@ import Data.Ord.Down (Down(..)) ...@@ -23,11 +22,15 @@ import Data.Ord.Down (Down(..))
import Data.Sequence (Seq, length) as Seq import Data.Sequence (Seq, length) as Seq
import Data.Set (Set) import Data.Set (Set)
import Data.Set as Set import Data.Set as Set
import Data.Symbol (SProxy(..)) import Data.Tuple (Tuple(..))
import Data.Tuple (Tuple(..), fst)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
import Unsafe.Coerce (unsafeCoerce)
import Gargantext.AsyncTasks as GAT import Gargantext.AsyncTasks as GAT
import Gargantext.Components.AutoUpdate (autoUpdateElt) import Gargantext.Components.AutoUpdate (autoUpdateElt)
import Gargantext.Components.NgramsTable.Components as NTC import Gargantext.Components.NgramsTable.Components as NTC
...@@ -37,7 +40,7 @@ import Gargantext.Components.Nodes.Lists.Types as NT ...@@ -37,7 +40,7 @@ import Gargantext.Components.Nodes.Lists.Types as NT
import Gargantext.Components.Table as TT import Gargantext.Components.Table as TT
import Gargantext.Components.Table.Types as TT import Gargantext.Components.Table.Types as TT
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError)
import Gargantext.Hooks.Loader (loader, useLoader) import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Routes (SessionRoute(..)) as R import Gargantext.Routes (SessionRoute(..)) as R
import Gargantext.Sessions (Session, get) import Gargantext.Sessions (Session, get)
import Gargantext.Types (CTabNgramType, OrderBy(..), SearchQuery, TabType, TermList(..), TermSize, termLists, termSizes) import Gargantext.Types (CTabNgramType, OrderBy(..), SearchQuery, TabType, TermList(..), TermSize, termLists, termSizes)
...@@ -46,20 +49,10 @@ import Gargantext.Utils.CacheAPI as GUC ...@@ -46,20 +49,10 @@ import Gargantext.Utils.CacheAPI as GUC
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Seq as Seq import Gargantext.Utils.Seq as Seq
import Gargantext.Utils.Toestand as T2 import Gargantext.Utils.Toestand as T2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
import Unsafe.Coerce (unsafeCoerce)
here :: R2.Here here :: R2.Here
here = R2.here "Gargantext.Components.NgramsTable" here = R2.here "Gargantext.Components.NgramsTable"
_ngramsChildren :: forall row. Lens' { ngramsChildren :: Map NgramsTerm Boolean | row } (Map NgramsTerm Boolean)
_ngramsChildren = prop (SProxy :: SProxy "ngramsChildren")
_ngramsSelection :: forall row. Lens' { ngramsSelection :: Set NgramsTerm | row } (Set NgramsTerm)
_ngramsSelection = prop (SProxy :: SProxy "ngramsSelection")
type State = type State =
CoreState ( CoreState (
ngramsChildren :: Map NgramsTerm Boolean ngramsChildren :: Map NgramsTerm Boolean
...@@ -278,27 +271,25 @@ loadedNgramsTable :: R2.Component Props ...@@ -278,27 +271,25 @@ loadedNgramsTable :: R2.Component Props
loadedNgramsTable = R.createElement loadedNgramsTableCpt loadedNgramsTable = R.createElement loadedNgramsTableCpt
loadedNgramsTableCpt :: R.Component Props loadedNgramsTableCpt :: R.Component Props
loadedNgramsTableCpt = here.component "loadedNgramsTable" cpt where loadedNgramsTableCpt = here.component "loadedNgramsTable" cpt where
cpt props@{ afterSync cpt { afterSync
, cacheState , cacheState
, mTotalRows , mTotalRows
, path , path
, reloadForest , reloadForest
, reloadRoot , reloadRoot
, state , state
, tabNgramType , tabNgramType
, tasks , tasks
, versioned: Versioned { data: initTable } , versioned: Versioned { data: initTable }
, withAutoUpdate } _ = do , withAutoUpdate } _ = do
state'@{ ngramsChildren, ngramsLocalPatch, ngramsParent, ngramsSelection, ngramsVersion } <- T.useLive T.unequal state state'@{ ngramsChildren, ngramsLocalPatch, ngramsParent, ngramsSelection } <- T.useLive T.unequal state
path'@{ listIds, params, scoreType, termListFilter, termSizeFilter } <- T.useLive T.unequal path path'@{ scoreType, termListFilter, termSizeFilter } <- T.useLive T.unequal path
params <- T.useFocused (_.params) (\a b -> b { params = a }) path params <- T.useFocused (_.params) (\a b -> b { params = a }) path
params'@{ orderBy } <- T.useLive T.unequal params params'@{ orderBy } <- T.useLive T.unequal params
searchQuery <- T.useFocused (_.searchQuery) (\a b -> b { searchQuery = a }) path searchQuery <- T.useFocused (_.searchQuery) (\a b -> b { searchQuery = a }) path
searchQuery' <- T.useLive T.unequal searchQuery searchQuery' <- T.useLive T.unequal searchQuery
let ngramsTable = applyNgramsPatches state' initTable let ngramsTable = applyNgramsPatches state' initTable
roots = rootsOf ngramsTable
rowMap (Tuple ng nre) = rowMap (Tuple ng nre) =
let ng_scores :: Map NgramsTerm (Additive Int) let ng_scores :: Map NgramsTerm (Additive Int)
ng_scores = ngramsTable ^. _NgramsTable <<< _ngrams_scores ng_scores = ngramsTable ^. _NgramsTable <<< _ngrams_scores
...@@ -317,7 +308,6 @@ loadedNgramsTableCpt = here.component "loadedNgramsTable" cpt where ...@@ -317,7 +308,6 @@ loadedNgramsTableCpt = here.component "loadedNgramsTable" cpt where
rowsFilter ngramsElement = rowsFilter ngramsElement =
if displayRow { ngramsElement if displayRow { ngramsElement
, ngramsParentRoot , ngramsParentRoot
, ngramsTable
, searchQuery: searchQuery' , searchQuery: searchQuery'
, state: state' , state: state'
, termListFilter , termListFilter
...@@ -477,17 +467,15 @@ mkDispatch { filteredRows ...@@ -477,17 +467,15 @@ mkDispatch { filteredRows
displayRow :: { ngramsElement :: NgramsElement displayRow :: { ngramsElement :: NgramsElement
, ngramsParentRoot :: Maybe NgramsTerm , ngramsParentRoot :: Maybe NgramsTerm
, ngramsTable :: NgramsTable
, searchQuery :: SearchQuery , searchQuery :: SearchQuery
, state :: State , state :: State
, termListFilter :: Maybe TermList , termListFilter :: Maybe TermList
, termSizeFilter :: Maybe TermSize } -> Boolean , termSizeFilter :: Maybe TermSize } -> Boolean
displayRow { ngramsElement: NgramsElement {ngrams, root, list} displayRow { ngramsElement: NgramsElement {ngrams, root, list}
, ngramsParentRoot , ngramsParentRoot
, ngramsTable , state: { ngramsChildren
, state: state@{ ngramsChildren , ngramsLocalPatch
, ngramsLocalPatch , ngramsParent }
, ngramsParent }
, searchQuery , searchQuery
, termListFilter , termListFilter
, termSizeFilter } = , termSizeFilter } =
...@@ -535,17 +523,17 @@ mainNgramsTable = R.createElement mainNgramsTableCpt ...@@ -535,17 +523,17 @@ mainNgramsTable = R.createElement mainNgramsTableCpt
mainNgramsTableCpt :: R.Component MainNgramsTableProps mainNgramsTableCpt :: R.Component MainNgramsTableProps
mainNgramsTableCpt = here.component "mainNgramsTable" cpt mainNgramsTableCpt = here.component "mainNgramsTable" cpt
where where
cpt props@{ afterSync cpt { afterSync
, cacheState , cacheState
, defaultListId , defaultListId
, path , path
, reloadForest , reloadForest
, reloadRoot , reloadRoot
, tabNgramType , tabNgramType
, tasks , tasks
, withAutoUpdate } _ = do , withAutoUpdate } _ = do
cacheState' <- T.useLive T.unequal cacheState cacheState' <- T.useLive T.unequal cacheState
path'@{ nodeId, tabType, session } <- T.useLive T.unequal path path' <- T.useLive T.unequal path
-- let path = initialPageParams session nodeId [defaultListId] tabType -- let path = initialPageParams session nodeId [defaultListId] tabType
...@@ -562,6 +550,7 @@ mainNgramsTableCpt = here.component "mainNgramsTable" cpt ...@@ -562,6 +550,7 @@ mainNgramsTableCpt = here.component "mainNgramsTable" cpt
, withAutoUpdate } [] , withAutoUpdate } []
useLoaderWithCacheAPI { useLoaderWithCacheAPI {
cacheEndpoint: versionEndpoint { defaultListId, path: path' } cacheEndpoint: versionEndpoint { defaultListId, path: path' }
, errorHandler
, handleResponse , handleResponse
, mkRequest , mkRequest
, path: path' , path: path'
...@@ -591,15 +580,15 @@ mainNgramsTableCpt = here.component "mainNgramsTable" cpt ...@@ -591,15 +580,15 @@ mainNgramsTableCpt = here.component "mainNgramsTable" cpt
-- NOTE With cache off -- NOTE With cache off
loader :: PageParams -> Aff (Either RESTError VersionedWithCountNgramsTable) loader :: PageParams -> Aff (Either RESTError VersionedWithCountNgramsTable)
loader path@{ listIds loader { listIds
, nodeId , nodeId
, params: { limit, offset, orderBy } , params: { limit, offset }
, searchQuery , searchQuery
, session , session
, tabType , tabType
, termListFilter , termListFilter
, termSizeFilter , termSizeFilter
} = } =
get session $ R.GetNgrams params (Just nodeId) get session $ R.GetNgrams params (Just nodeId)
where where
params = { limit params = { limit
...@@ -618,12 +607,7 @@ mainNgramsTableCpt = here.component "mainNgramsTable" cpt ...@@ -618,12 +607,7 @@ mainNgramsTableCpt = here.component "mainNgramsTable" cpt
where where
url { listIds url { listIds
, nodeId , nodeId
, params: { limit, offset, orderBy }
, searchQuery
, scoreType
, tabType , tabType
, termListFilter
, termSizeFilter
} = R.GetNgramsTableAll { listIds } = R.GetNgramsTableAll { listIds
, tabType } (Just nodeId) , tabType } (Just nodeId)
...@@ -643,15 +627,15 @@ mainNgramsTablePaint = R.createElement mainNgramsTablePaintCpt ...@@ -643,15 +627,15 @@ mainNgramsTablePaint = R.createElement mainNgramsTablePaintCpt
mainNgramsTablePaintCpt :: R.Component MainNgramsTablePaintProps mainNgramsTablePaintCpt :: R.Component MainNgramsTablePaintProps
mainNgramsTablePaintCpt = here.component "mainNgramsTablePaint" cpt mainNgramsTablePaintCpt = here.component "mainNgramsTablePaint" cpt
where where
cpt props@{ afterSync cpt { afterSync
, cacheState , cacheState
, path , path
, reloadForest , reloadForest
, reloadRoot , reloadRoot
, tabNgramType , tabNgramType
, tasks , tasks
, versioned , versioned
, withAutoUpdate } _ = do , withAutoUpdate } _ = do
state <- T.useBox $ initialState versioned state <- T.useBox $ initialState versioned
pure $ loadedNgramsTable { afterSync pure $ loadedNgramsTable { afterSync
...@@ -680,15 +664,15 @@ mainNgramsTablePaintNoCache = R.createElement mainNgramsTablePaintNoCacheCpt ...@@ -680,15 +664,15 @@ mainNgramsTablePaintNoCache = R.createElement mainNgramsTablePaintNoCacheCpt
mainNgramsTablePaintNoCacheCpt :: R.Component MainNgramsTablePaintNoCacheProps mainNgramsTablePaintNoCacheCpt :: R.Component MainNgramsTablePaintNoCacheProps
mainNgramsTablePaintNoCacheCpt = here.component "mainNgramsTablePaintNoCache" cpt mainNgramsTablePaintNoCacheCpt = here.component "mainNgramsTablePaintNoCache" cpt
where where
cpt props@{ afterSync cpt { afterSync
, cacheState , cacheState
, path , path
, reloadForest , reloadForest
, reloadRoot , reloadRoot
, tabNgramType , tabNgramType
, tasks , tasks
, versionedWithCount , versionedWithCount
, withAutoUpdate } _ = do , withAutoUpdate } _ = do
let count /\ versioned = toVersioned versionedWithCount let count /\ versioned = toVersioned versionedWithCount
state <- T.useBox $ initialState versioned state <- T.useBox $ initialState versioned
......
...@@ -2,20 +2,21 @@ module Gargantext.Components.NgramsTable.Loader where ...@@ -2,20 +2,21 @@ module Gargantext.Components.NgramsTable.Loader where
import Gargantext.Prelude import Gargantext.Prelude
import Affjax (Error(..))
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.Maybe (Maybe(..), maybe, isJust) import Data.Maybe (Maybe(..), maybe, isJust)
import Effect (Effect)
import Effect.Aff (Aff, launchAff_, throwError) import Effect.Aff (Aff, launchAff_, throwError)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Effect.Exception (error) import Effect.Exception (error)
import Gargantext.Components.LoadingSpinner (loadingSpinner) import Gargantext.Components.LoadingSpinner (loadingSpinner)
import Gargantext.Components.NgramsTable.Core (Version, Versioned(..)) import Gargantext.Components.NgramsTable.Core (Version, Versioned(..))
import Gargantext.Config.REST (RESTError) import Gargantext.Config.REST (RESTError(..))
import Gargantext.Utils.CacheAPI as GUC import Gargantext.Utils.CacheAPI as GUC
import Reactix as R import Reactix as R
import Simple.JSON as JSON import Simple.JSON as JSON
import Toestand as T import Toestand as T
cacheName :: String cacheName :: String
cacheName = "ngrams-cache-api-loader" cacheName = "ngrams-cache-api-loader"
...@@ -25,22 +26,24 @@ clearCache _ = GUC.delete $ GUC.CacheName cacheName ...@@ -25,22 +26,24 @@ clearCache _ = GUC.delete $ GUC.CacheName cacheName
type LoaderWithCacheAPIProps path res ret = ( type LoaderWithCacheAPIProps path res ret = (
cacheEndpoint :: path -> Aff (Either RESTError Version) cacheEndpoint :: path -> Aff (Either RESTError Version)
, errorHandler :: RESTError -> Effect Unit
, handleResponse :: Versioned res -> ret , handleResponse :: Versioned res -> ret
, mkRequest :: path -> GUC.Request , mkRequest :: path -> GUC.Request
, path :: path , path :: path
, renderer :: ret -> R.Element , renderer :: ret -> R.Element
) )
useLoaderWithCacheAPI :: forall path res ret. Eq path => JSON.ReadForeign res => Eq ret => useLoaderWithCacheAPI :: forall path res ret. Eq path => JSON.ReadForeign res => Eq ret =>
Record (LoaderWithCacheAPIProps path res ret) Record (LoaderWithCacheAPIProps path res ret)
-> R.Hooks R.Element -> R.Hooks R.Element
useLoaderWithCacheAPI { cacheEndpoint, handleResponse, mkRequest, path, renderer } = do useLoaderWithCacheAPI { cacheEndpoint, errorHandler, handleResponse, mkRequest, path, renderer } = do
state <- T.useBox Nothing state <- T.useBox Nothing
state' <- T.useLive T.unequal state state' <- T.useLive T.unequal state
useCachedAPILoaderEffect { cacheEndpoint useCachedAPILoaderEffect { cacheEndpoint
, errorHandler
, handleResponse , handleResponse
, mkRequest , mkRequest
, path , path
...@@ -49,6 +52,7 @@ useLoaderWithCacheAPI { cacheEndpoint, handleResponse, mkRequest, path, renderer ...@@ -49,6 +52,7 @@ useLoaderWithCacheAPI { cacheEndpoint, handleResponse, mkRequest, path, renderer
type LoaderWithCacheAPIEffectProps path res ret = ( type LoaderWithCacheAPIEffectProps path res ret = (
cacheEndpoint :: path -> Aff (Either RESTError Version) cacheEndpoint :: path -> Aff (Either RESTError Version)
, errorHandler :: RESTError -> Effect Unit
, handleResponse :: Versioned res -> ret , handleResponse :: Versioned res -> ret
, mkRequest :: path -> GUC.Request , mkRequest :: path -> GUC.Request
, path :: path , path :: path
...@@ -59,6 +63,7 @@ useCachedAPILoaderEffect :: forall path res ret. Eq path => JSON.ReadForeign res ...@@ -59,6 +63,7 @@ useCachedAPILoaderEffect :: forall path res ret. Eq path => JSON.ReadForeign res
Record (LoaderWithCacheAPIEffectProps path res ret) Record (LoaderWithCacheAPIEffectProps path res ret)
-> R.Hooks Unit -> R.Hooks Unit
useCachedAPILoaderEffect { cacheEndpoint useCachedAPILoaderEffect { cacheEndpoint
, errorHandler
, handleResponse , handleResponse
, mkRequest , mkRequest
, path , path
...@@ -77,10 +82,10 @@ useCachedAPILoaderEffect { cacheEndpoint ...@@ -77,10 +82,10 @@ useCachedAPILoaderEffect { cacheEndpoint
launchAff_ $ do launchAff_ $ do
cache <- GUC.openCache $ GUC.CacheName cacheName cache <- GUC.openCache $ GUC.CacheName cacheName
-- TODO Parallelize? -- TODO Parallelize?
vr@(Versioned { version, "data": d }) <- GUC.cachedJson cache req vr@(Versioned { version }) <- GUC.cachedJson cache req
eCacheReal <- cacheEndpoint path eCacheReal <- cacheEndpoint path
case eCacheReal of case eCacheReal of
Left err -> throwError $ error $ "[useCachedAPILoaderEffect] RESTError" Left err -> liftEffect $ errorHandler err
Right cacheReal -> do Right cacheReal -> do
val <- if version == cacheReal then val <- if version == cacheReal then
pure vr pure vr
...@@ -92,8 +97,9 @@ useCachedAPILoaderEffect { cacheEndpoint ...@@ -92,8 +97,9 @@ useCachedAPILoaderEffect { cacheEndpoint
_ <- GUC.deleteReq cache req _ <- GUC.deleteReq cache req
vr'@(Versioned { version: version', data: _ }) <- GUC.cachedJson cache req vr'@(Versioned { version: version', data: _ }) <- GUC.cachedJson cache req
if version' == cacheReal then if version' == cacheReal then
pure vr' pure vr'
else else do
throwError $ error $ "[useCachedAPILoaderEffect] Fetched clean cache but hashes don't match: " <> show version <> " != " <> show cacheReal liftEffect $ errorHandler $ SendResponseError $ RequestContentError $ "[useCachedAPILoaderEffect] Fetched clean cache but hashes don't match: " <> show version <> " != " <> show cacheReal
throwError $ error $"[useCachedAPILoaderEffect] Fetched clean cache but hashes don't match: " <> show version <> " != " <> show cacheReal
liftEffect $ do liftEffect $ do
T.write_ (Just $ handleResponse val) state T.write_ (Just $ handleResponse val) state
...@@ -2,8 +2,6 @@ module Gargantext.Hooks.Loader where ...@@ -2,8 +2,6 @@ module Gargantext.Hooks.Loader where
import Gargantext.Prelude import Gargantext.Prelude
import Control.Bind ((=<<))
import Control.Monad.RWS (state)
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.Generic.Rep (class Generic) import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe(..), isJust, maybe) import Data.Maybe (Maybe(..), isJust, maybe)
...@@ -13,7 +11,6 @@ import Effect.Aff (Aff, launchAff_, throwError) ...@@ -13,7 +11,6 @@ import Effect.Aff (Aff, launchAff_, throwError)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Effect.Exception (error) import Effect.Exception (error)
import Reactix as R import Reactix as R
import Record as Record
import Simple.JSON as JSON import Simple.JSON as JSON
import Toestand as T import Toestand as T
...@@ -106,7 +103,6 @@ type LoaderWithCacheAPIProps path res ret = ( ...@@ -106,7 +103,6 @@ type LoaderWithCacheAPIProps path res ret = (
, renderer :: ret -> R.Element , renderer :: ret -> R.Element
) )
useLoaderWithCacheAPI :: forall path res ret. useLoaderWithCacheAPI :: forall path res ret.
Eq ret => Eq path => JSON.ReadForeign res => Eq ret => Eq path => JSON.ReadForeign res =>
Record (LoaderWithCacheAPIProps path res ret) Record (LoaderWithCacheAPIProps path res ret)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment