From bb5575cd2783ca670b908fb158b9b120a64be6c2 Mon Sep 17 00:00:00 2001 From: Art Lowel <art@ArtMac.local> Date: Wed, 22 Feb 2017 12:03:22 +0100 Subject: [PATCH] Refactored Data Services --- src/app/core/cache/cache.reducers.ts | 17 ++++++ src/app/core/cache/object-cache.actions.ts | 33 +++++++++++ src/app/core/cache/object-cache.reducer.ts | 58 +++++++++++++++++++ .../object-cache.service.ts} | 24 ++++---- .../request-cache.actions.ts} | 36 ++++++------ .../request-cache.reducer.ts} | 38 ++++++------ src/app/core/core.module.ts | 4 +- src/app/core/core.reducers.ts | 5 +- .../core/data-services/cache/cache.actions.ts | 33 ----------- .../core/data-services/cache/cache.reducer.ts | 58 ------------------- .../data-services/collection-data.effects.ts | 10 ++-- .../data-services/collection-data.service.ts | 8 +-- src/app/core/data-services/data.effects.ts | 40 ++++++------- src/app/core/data-services/data.service.ts | 24 ++++---- .../core/data-services/item-data.effects.ts | 10 ++-- .../core/data-services/item-data.service.ts | 8 +-- src/app/core/shared/dspace-object.model.ts | 2 +- src/backend/api.ts | 8 +-- 18 files changed, 215 insertions(+), 201 deletions(-) create mode 100644 src/app/core/cache/cache.reducers.ts create mode 100644 src/app/core/cache/object-cache.actions.ts create mode 100644 src/app/core/cache/object-cache.reducer.ts rename src/app/core/{data-services/cache/cache.service.ts => cache/object-cache.service.ts} (54%) rename src/app/core/{data-services/data.actions.ts => cache/request-cache.actions.ts} (61%) rename src/app/core/{data-services/data.reducer.ts => cache/request-cache.reducer.ts} (57%) delete mode 100644 src/app/core/data-services/cache/cache.actions.ts delete mode 100644 src/app/core/data-services/cache/cache.reducer.ts diff --git a/src/app/core/cache/cache.reducers.ts b/src/app/core/cache/cache.reducers.ts new file mode 100644 index 0000000000..2edd1e8ebf --- /dev/null +++ b/src/app/core/cache/cache.reducers.ts @@ -0,0 +1,17 @@ +import { combineReducers } from "@ngrx/store"; +import { RequestCacheState, requestCacheReducer } from "./request-cache.reducer"; +import { ObjectCacheState, objectCacheReducer } from "./object-cache.reducer"; + +export interface CacheState { + request: RequestCacheState, + object: ObjectCacheState +} + +export const reducers = { + request: requestCacheReducer, + object: objectCacheReducer +}; + +export function cacheReducer(state: any, action: any) { + return combineReducers(reducers)(state, action); +} diff --git a/src/app/core/cache/object-cache.actions.ts b/src/app/core/cache/object-cache.actions.ts new file mode 100644 index 0000000000..1053ea66ed --- /dev/null +++ b/src/app/core/cache/object-cache.actions.ts @@ -0,0 +1,33 @@ +import { Action } from "@ngrx/store"; +import { type } from "../../shared/ngrx/type"; +import { CacheableObject } from "./object-cache.reducer"; + +export const ObjectCacheActionTypes = { + ADD: type('dspace/core/cache/object/ADD'), + REMOVE: type('dspace/core/cache/object/REMOVE') +}; + +export class AddToObjectCacheAction implements Action { + type = ObjectCacheActionTypes.ADD; + payload: { + objectToCache: CacheableObject; + msToLive: number; + }; + + constructor(objectToCache: CacheableObject, msToLive: number) { + this.payload = { objectToCache, msToLive }; + } +} + +export class RemoveFromObjectCacheAction implements Action { + type = ObjectCacheActionTypes.REMOVE; + payload: string; + + constructor(uuid: string) { + this.payload = uuid; + } +} + +export type ObjectCacheAction + = AddToObjectCacheAction + | RemoveFromObjectCacheAction diff --git a/src/app/core/cache/object-cache.reducer.ts b/src/app/core/cache/object-cache.reducer.ts new file mode 100644 index 0000000000..9e3b6f50e9 --- /dev/null +++ b/src/app/core/cache/object-cache.reducer.ts @@ -0,0 +1,58 @@ +import { ObjectCacheAction, ObjectCacheActionTypes, AddToObjectCacheAction, RemoveFromObjectCacheAction } from "./object-cache.actions"; +import { hasValue } from "../../shared/empty.util"; + +export interface CacheableObject { + uuid: string; +} + +export interface ObjectCacheEntry { + data: CacheableObject; + timeAdded: number; + msToLive: number; +} + +export interface ObjectCacheState { + [uuid: string]: ObjectCacheEntry +} + +// Object.create(null) ensures the object has no default js properties (e.g. `__proto__`) +const initialState: ObjectCacheState = Object.create(null); + +export const objectCacheReducer = (state = initialState, action: ObjectCacheAction): ObjectCacheState => { + switch (action.type) { + + case ObjectCacheActionTypes.ADD: { + return addToObjectCache(state, <AddToObjectCacheAction>action); + } + + case ObjectCacheActionTypes.REMOVE: { + return removeFromObjectCache(state, <RemoveFromObjectCacheAction>action) + } + + default: { + return state; + } + } +}; + +function addToObjectCache(state: ObjectCacheState, action: AddToObjectCacheAction): ObjectCacheState { + return Object.assign({}, state, { + [action.payload.objectToCache.uuid]: { + data: action.payload.objectToCache, + timeAdded: new Date().getTime(), + msToLive: action.payload.msToLive + } + }); +} + +function removeFromObjectCache(state: ObjectCacheState, action: RemoveFromObjectCacheAction): ObjectCacheState { + if (hasValue(state[action.payload])) { + let newObjectCache = Object.assign({}, state); + delete newObjectCache[action.payload]; + + return newObjectCache; + } + else { + return state; + } +} diff --git a/src/app/core/data-services/cache/cache.service.ts b/src/app/core/cache/object-cache.service.ts similarity index 54% rename from src/app/core/data-services/cache/cache.service.ts rename to src/app/core/cache/object-cache.service.ts index d8c73ec1cb..ca5d0ec658 100644 --- a/src/app/core/data-services/cache/cache.service.ts +++ b/src/app/core/cache/object-cache.service.ts @@ -1,28 +1,28 @@ import { Injectable } from "@angular/core"; import { Store } from "@ngrx/store"; -import { CacheState, CacheEntry, CacheableObject } from "./cache.reducer"; -import { AddToCacheAction, RemoveFromCacheAction } from "./cache.actions"; +import { ObjectCacheState, ObjectCacheEntry, CacheableObject } from "./object-cache.reducer"; +import { AddToObjectCacheAction, RemoveFromObjectCacheAction } from "./object-cache.actions"; import { Observable } from "rxjs"; -import { hasNoValue } from "../../../shared/empty.util"; +import { hasNoValue } from "../../shared/empty.util"; @Injectable() -export class CacheService { +export class ObjectCacheService { constructor( - private store: Store<CacheState> + private store: Store<ObjectCacheState> ) {} add(objectToCache: CacheableObject, msToLive: number): void { - this.store.dispatch(new AddToCacheAction(objectToCache, msToLive)); + this.store.dispatch(new AddToObjectCacheAction(objectToCache, msToLive)); } remove(uuid: string): void { - this.store.dispatch(new RemoveFromCacheAction(uuid)); + this.store.dispatch(new RemoveFromObjectCacheAction(uuid)); } get<T extends CacheableObject>(uuid: string): Observable<T> { - return this.store.select<CacheEntry>('core', 'cache', uuid) + return this.store.select<ObjectCacheEntry>('core', 'cache', 'object', uuid) .filter(entry => this.isValid(entry)) - .map((entry: CacheEntry) => <T> entry.data); + .map((entry: ObjectCacheEntry) => <T> entry.data); } getList<T extends CacheableObject>(uuids: Array<string>): Observable<Array<T>> { @@ -34,14 +34,14 @@ export class CacheService { has(uuid: string): boolean { let result: boolean; - this.store.select<CacheEntry>('core', 'cache', uuid) + this.store.select<ObjectCacheEntry>('core', 'cache', 'object', uuid) .take(1) .subscribe(entry => result = this.isValid(entry)); return result; } - private isValid(entry: CacheEntry): boolean { + private isValid(entry: ObjectCacheEntry): boolean { if (hasNoValue(entry)) { return false; } @@ -49,7 +49,7 @@ export class CacheService { const timeOutdated = entry.timeAdded + entry.msToLive; const isOutDated = new Date().getTime() > timeOutdated; if (isOutDated) { - this.store.dispatch(new RemoveFromCacheAction(entry.data.uuid)); + this.store.dispatch(new RemoveFromObjectCacheAction(entry.data.uuid)); } return !isOutDated; } diff --git a/src/app/core/data-services/data.actions.ts b/src/app/core/cache/request-cache.actions.ts similarity index 61% rename from src/app/core/data-services/data.actions.ts rename to src/app/core/cache/request-cache.actions.ts index caf37331b0..014bc1b059 100644 --- a/src/app/core/data-services/data.actions.ts +++ b/src/app/core/cache/request-cache.actions.ts @@ -4,15 +4,15 @@ import { type } from "../../shared/ngrx/type"; import { PaginationOptions } from "../shared/pagination-options.model"; import { SortOptions } from "../shared/sort-options.model"; -export const DataActionTypes = { - FIND_BY_ID_REQUEST: type('dspace/core/data/FIND_BY_ID_REQUEST'), - FIND_ALL_REQUEST: type('dspace/core/data/FIND_ALL_REQUEST'), - SUCCESS: type('dspace/core/data/SUCCESS'), - ERROR: type('dspace/core/data/ERROR') +export const RequestCacheActionTypes = { + FIND_BY_ID_REQUEST: type('dspace/core/cache/request/FIND_BY_ID_REQUEST'), + FIND_ALL_REQUEST: type('dspace/core/cache/request/FIND_ALL_REQUEST'), + SUCCESS: type('dspace/core/cache/request/SUCCESS'), + ERROR: type('dspace/core/cache/request/ERROR') }; -export class DataFindAllRequestAction implements Action { - type = DataActionTypes.FIND_ALL_REQUEST; +export class FindAllRequestCacheAction implements Action { + type = RequestCacheActionTypes.FIND_ALL_REQUEST; payload: { key: string, service: OpaqueToken, @@ -38,8 +38,8 @@ export class DataFindAllRequestAction implements Action { } } -export class DataFindByIDRequestAction implements Action { - type = DataActionTypes.FIND_BY_ID_REQUEST; +export class FindByIDRequestCacheAction implements Action { + type = RequestCacheActionTypes.FIND_BY_ID_REQUEST; payload: { key: string, service: OpaqueToken, @@ -59,8 +59,8 @@ export class DataFindByIDRequestAction implements Action { } } -export class DataSuccessAction implements Action { - type = DataActionTypes.SUCCESS; +export class RequestCacheSuccessAction implements Action { + type = RequestCacheActionTypes.SUCCESS; payload: { key: string, resourceUUIDs: Array<string> @@ -74,8 +74,8 @@ export class DataSuccessAction implements Action { } } -export class DataErrorAction implements Action { - type = DataActionTypes.ERROR; +export class RequestCacheErrorAction implements Action { + type = RequestCacheActionTypes.ERROR; payload: { key: string, errorMessage: string @@ -89,8 +89,8 @@ export class DataErrorAction implements Action { } } -export type DataAction - = DataFindAllRequestAction - | DataFindByIDRequestAction - | DataSuccessAction - | DataErrorAction; +export type RequestCacheAction + = FindAllRequestCacheAction + | FindByIDRequestCacheAction + | RequestCacheSuccessAction + | RequestCacheErrorAction; diff --git a/src/app/core/data-services/data.reducer.ts b/src/app/core/cache/request-cache.reducer.ts similarity index 57% rename from src/app/core/data-services/data.reducer.ts rename to src/app/core/cache/request-cache.reducer.ts index 3641e790c7..320bf6251d 100644 --- a/src/app/core/data-services/data.reducer.ts +++ b/src/app/core/cache/request-cache.reducer.ts @@ -1,12 +1,12 @@ import { PaginationOptions } from "../shared/pagination-options.model"; import { SortOptions } from "../shared/sort-options.model"; import { - DataAction, DataActionTypes, DataFindAllRequestAction, - DataSuccessAction, DataErrorAction, DataFindByIDRequestAction -} from "./data.actions"; + RequestCacheAction, RequestCacheActionTypes, FindAllRequestCacheAction, + RequestCacheSuccessAction, RequestCacheErrorAction, FindByIDRequestCacheAction +} from "./request-cache.actions"; import { OpaqueToken } from "@angular/core"; -export interface DataRequestState { +export interface CachedRequest { service: OpaqueToken scopeID: string; resourceID: string; @@ -20,30 +20,30 @@ export interface DataRequestState { msToLive: number; } -export interface DataState { - [key: string]: DataRequestState +export interface RequestCacheState { + [key: string]: CachedRequest } // Object.create(null) ensures the object has no default js properties (e.g. `__proto__`) const initialState = Object.create(null); -export const dataReducer = (state = initialState, action: DataAction): DataState => { +export const requestCacheReducer = (state = initialState, action: RequestCacheAction): RequestCacheState => { switch (action.type) { - case DataActionTypes.FIND_ALL_REQUEST: { - return findAllRequest(state, <DataFindAllRequestAction> action); + case RequestCacheActionTypes.FIND_ALL_REQUEST: { + return findAllRequest(state, <FindAllRequestCacheAction> action); } - case DataActionTypes.FIND_BY_ID_REQUEST: { - return findByIDRequest(state, <DataFindByIDRequestAction> action); + case RequestCacheActionTypes.FIND_BY_ID_REQUEST: { + return findByIDRequest(state, <FindByIDRequestCacheAction> action); } - case DataActionTypes.SUCCESS: { - return success(state, <DataSuccessAction> action); + case RequestCacheActionTypes.SUCCESS: { + return success(state, <RequestCacheSuccessAction> action); } - case DataActionTypes.ERROR: { - return error(state, <DataErrorAction> action); + case RequestCacheActionTypes.ERROR: { + return error(state, <RequestCacheErrorAction> action); } default: { @@ -52,7 +52,7 @@ export const dataReducer = (state = initialState, action: DataAction): DataState } }; -function findAllRequest(state: DataState, action: DataFindAllRequestAction): DataState { +function findAllRequest(state: RequestCacheState, action: FindAllRequestCacheAction): RequestCacheState { return Object.assign({}, state, { [action.payload.key]: { service: action.payload.service, @@ -66,7 +66,7 @@ function findAllRequest(state: DataState, action: DataFindAllRequestAction): Dat }); } -function findByIDRequest(state: DataState, action: DataFindByIDRequestAction): DataState { +function findByIDRequest(state: RequestCacheState, action: FindByIDRequestCacheAction): RequestCacheState { return Object.assign({}, state, { [action.payload.key]: { service: action.payload.service, @@ -78,7 +78,7 @@ function findByIDRequest(state: DataState, action: DataFindByIDRequestAction): D }); } -function success(state: DataState, action: DataSuccessAction): DataState { +function success(state: RequestCacheState, action: RequestCacheSuccessAction): RequestCacheState { return Object.assign({}, state, { [action.payload.key]: Object.assign({}, state[action.payload.key], { isLoading: false, @@ -88,7 +88,7 @@ function success(state: DataState, action: DataSuccessAction): DataState { }); } -function error(state: DataState, action: DataErrorAction): DataState { +function error(state: RequestCacheState, action: RequestCacheErrorAction): RequestCacheState { return Object.assign({}, state, { [action.payload.key]: Object.assign({}, state[action.payload.key], { isLoading: false, diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 847f6f8287..a2fd79ffbc 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -4,7 +4,7 @@ import { SharedModule } from "../shared/shared.module"; import { isNotEmpty } from "../shared/empty.util"; import { FooterComponent } from "./footer/footer.component"; import { DSpaceRESTv2Service } from "./dspace-rest-v2/dspace-rest-v2.service"; -import { CacheService } from "./data-services/cache/cache.service"; +import { ObjectCacheService } from "./cache/object-cache.service"; import { CollectionDataService } from "./data-services/collection-data.service"; import { ItemDataService } from "./data-services/item-data.service"; @@ -25,7 +25,7 @@ const PROVIDERS = [ CollectionDataService, ItemDataService, DSpaceRESTv2Service, - CacheService + ObjectCacheService ]; @NgModule({ diff --git a/src/app/core/core.reducers.ts b/src/app/core/core.reducers.ts index d39039c499..71f25ee0b0 100644 --- a/src/app/core/core.reducers.ts +++ b/src/app/core/core.reducers.ts @@ -1,14 +1,11 @@ import { combineReducers } from "@ngrx/store"; -import { CacheState, cacheReducer } from "./data-services/cache/cache.reducer"; -import { dataReducer, DataState } from "./data-services/data.reducer"; +import { CacheState, cacheReducer } from "./cache/cache.reducers"; export interface CoreState { - data: DataState, cache: CacheState } export const reducers = { - data: dataReducer, cache: cacheReducer }; diff --git a/src/app/core/data-services/cache/cache.actions.ts b/src/app/core/data-services/cache/cache.actions.ts deleted file mode 100644 index 43146f5ce9..0000000000 --- a/src/app/core/data-services/cache/cache.actions.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Action } from "@ngrx/store"; -import { type } from "../../../shared/ngrx/type"; -import { CacheableObject } from "./cache.reducer"; - -export const CacheActionTypes = { - ADD: type('dspace/core/data/cache/ADD'), - REMOVE: type('dspace/core/data/cache/REMOVE') -}; - -export class AddToCacheAction implements Action { - type = CacheActionTypes.ADD; - payload: { - objectToCache: CacheableObject; - msToLive: number; - }; - - constructor(objectToCache: CacheableObject, msToLive: number) { - this.payload = { objectToCache, msToLive }; - } -} - -export class RemoveFromCacheAction implements Action { - type = CacheActionTypes.REMOVE; - payload: string; - - constructor(uuid: string) { - this.payload = uuid; - } -} - -export type CacheAction - = AddToCacheAction - | RemoveFromCacheAction diff --git a/src/app/core/data-services/cache/cache.reducer.ts b/src/app/core/data-services/cache/cache.reducer.ts deleted file mode 100644 index 59b567e939..0000000000 --- a/src/app/core/data-services/cache/cache.reducer.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { CacheAction, CacheActionTypes, AddToCacheAction, RemoveFromCacheAction } from "./cache.actions"; -import { hasValue } from "../../../shared/empty.util"; - -export interface CacheableObject { - uuid: string; -} - -export interface CacheEntry { - data: CacheableObject; - timeAdded: number; - msToLive: number; -} - -export interface CacheState { - [uuid: string]: CacheEntry -} - -// Object.create(null) ensures the object has no default js properties (e.g. `__proto__`) -const initialState: CacheState = Object.create(null); - -export const cacheReducer = (state = initialState, action: CacheAction): CacheState => { - switch (action.type) { - - case CacheActionTypes.ADD: { - return addToCache(state, <AddToCacheAction>action); - } - - case CacheActionTypes.REMOVE: { - return removeFromCache(state, <RemoveFromCacheAction>action) - } - - default: { - return state; - } - } -}; - -function addToCache(state: CacheState, action: AddToCacheAction): CacheState { - return Object.assign({}, state, { - [action.payload.objectToCache.uuid]: { - data: action.payload.objectToCache, - timeAdded: new Date().getTime(), - msToLive: action.payload.msToLive - } - }); -} - -function removeFromCache(state: CacheState, action: RemoveFromCacheAction): CacheState { - if (hasValue(state[action.payload])) { - let newCache = Object.assign({}, state); - delete newCache[action.payload]; - - return newCache; - } - else { - return state; - } -} diff --git a/src/app/core/data-services/collection-data.effects.ts b/src/app/core/data-services/collection-data.effects.ts index 9daacf999d..03bec274bc 100644 --- a/src/app/core/data-services/collection-data.effects.ts +++ b/src/app/core/data-services/collection-data.effects.ts @@ -3,10 +3,10 @@ import { DataEffects } from "./data.effects"; import { Serializer } from "../serializer"; import { Collection } from "../shared/collection.model"; import { DSpaceRESTv2Serializer } from "../dspace-rest-v2/dspace-rest-v2.serializer"; -import { CacheService } from "./cache/cache.service"; +import { ObjectCacheService } from "../cache/object-cache.service"; import { DSpaceRESTv2Service } from "../dspace-rest-v2/dspace-rest-v2.service"; import { Actions, Effect } from "@ngrx/effects"; -import { DataFindAllRequestAction, DataFindByIDRequestAction } from "./data.actions"; +import { FindAllRequestCacheAction, FindByIDRequestCacheAction } from "../cache/request-cache.actions"; import { CollectionDataService } from "./collection-data.service"; @Injectable() @@ -14,17 +14,17 @@ export class CollectionDataEffects extends DataEffects<Collection> { constructor( actions$: Actions, restApi: DSpaceRESTv2Service, - cache: CacheService, + cache: ObjectCacheService, dataService: CollectionDataService ) { super(actions$, restApi, cache, dataService); } - protected getFindAllEndpoint(action: DataFindAllRequestAction): string { + protected getFindAllEndpoint(action: FindAllRequestCacheAction): string { return '/collections'; } - protected getFindByIdEndpoint(action: DataFindByIDRequestAction): string { + protected getFindByIdEndpoint(action: FindByIDRequestCacheAction): string { return `/collections/${action.payload.resourceID}`; } diff --git a/src/app/core/data-services/collection-data.service.ts b/src/app/core/data-services/collection-data.service.ts index 9f4e2ed902..fdfaaa97ac 100644 --- a/src/app/core/data-services/collection-data.service.ts +++ b/src/app/core/data-services/collection-data.service.ts @@ -2,16 +2,16 @@ import { Injectable, OpaqueToken } from "@angular/core"; import { Store } from "@ngrx/store"; import { DataService } from "./data.service"; import { Collection } from "../shared/collection.model"; -import { CacheService } from "./cache/cache.service"; -import { DataState } from "./data.reducer"; +import { ObjectCacheService } from "../cache/object-cache.service"; +import { RequestCacheState } from "../cache/request-cache.reducer"; @Injectable() export class CollectionDataService extends DataService<Collection> { name = new OpaqueToken('CollectionDataService'); constructor( - store: Store<DataState>, - cache: CacheService + store: Store<RequestCacheState>, + cache: ObjectCacheService ) { super(store, cache); } diff --git a/src/app/core/data-services/data.effects.ts b/src/app/core/data-services/data.effects.ts index 362471bdfb..aaafda598b 100644 --- a/src/app/core/data-services/data.effects.ts +++ b/src/app/core/data-services/data.effects.ts @@ -2,25 +2,25 @@ import { Actions, Effect } from "@ngrx/effects"; import { Observable } from "rxjs"; import { DSpaceRESTV2Response } from "../dspace-rest-v2/dspace-rest-v2-response.model"; import { DSpaceRESTv2Service } from "../dspace-rest-v2/dspace-rest-v2.service"; -import { CacheService } from "./cache/cache.service"; +import { ObjectCacheService } from "../cache/object-cache.service"; import { GlobalConfig } from "../../../config"; -import { CacheableObject } from "./cache/cache.reducer"; +import { CacheableObject } from "../cache/object-cache.reducer"; import { Serializer } from "../serializer"; import { - DataActionTypes, DataFindAllRequestAction, DataSuccessAction, - DataErrorAction, DataFindByIDRequestAction, DataAction -} from "./data.actions"; + RequestCacheActionTypes, FindAllRequestCacheAction, RequestCacheSuccessAction, + RequestCacheErrorAction, FindByIDRequestCacheAction +} from "../cache/request-cache.actions"; import { DataService } from "./data.service"; export abstract class DataEffects<T extends CacheableObject> { - protected abstract getFindAllEndpoint(action: DataFindAllRequestAction): string; - protected abstract getFindByIdEndpoint(action: DataFindByIDRequestAction): string; + protected abstract getFindAllEndpoint(action: FindAllRequestCacheAction): string; + protected abstract getFindByIdEndpoint(action: FindByIDRequestCacheAction): string; protected abstract getSerializer(): Serializer<T>; constructor( private actions$: Actions, private restApi: DSpaceRESTv2Service, - private cache: CacheService, + private objectCache: ObjectCacheService, private dataService: DataService<T> ) {} @@ -28,33 +28,33 @@ export abstract class DataEffects<T extends CacheableObject> { // because currently the cache is more of an object store. We need to move // more towards memoization for things like this. protected findAll = this.actions$ - .ofType(DataActionTypes.FIND_ALL_REQUEST) - .filter((action: DataFindAllRequestAction) => action.payload.service === this.dataService.name) - .switchMap((action: DataFindAllRequestAction) => { + .ofType(RequestCacheActionTypes.FIND_ALL_REQUEST) + .filter((action: FindAllRequestCacheAction) => action.payload.service === this.dataService.name) + .switchMap((action: FindAllRequestCacheAction) => { //TODO scope, pagination, sorting -> when we know how that works in rest return this.restApi.get(this.getFindAllEndpoint(action)) .map((data: DSpaceRESTV2Response) => this.getSerializer().deserializeArray(data)) .do((ts: T[]) => { ts.forEach((t) => { - this.cache.add(t, GlobalConfig.cache.msToLive); + this.objectCache.add(t, GlobalConfig.cache.msToLive); }); }) .map((ts: Array<T>) => ts.map(t => t.uuid)) - .map((ids: Array<string>) => new DataSuccessAction(action.payload.key, ids)) - .catch((errorMsg: string) => Observable.of(new DataErrorAction(action.payload.key, errorMsg))); + .map((ids: Array<string>) => new RequestCacheSuccessAction(action.payload.key, ids)) + .catch((errorMsg: string) => Observable.of(new RequestCacheErrorAction(action.payload.key, errorMsg))); }); protected findById = this.actions$ - .ofType(DataActionTypes.FIND_BY_ID_REQUEST) - .filter((action: DataFindAllRequestAction) => action.payload.service === this.dataService.name) - .switchMap((action: DataFindByIDRequestAction) => { + .ofType(RequestCacheActionTypes.FIND_BY_ID_REQUEST) + .filter((action: FindAllRequestCacheAction) => action.payload.service === this.dataService.name) + .switchMap((action: FindByIDRequestCacheAction) => { return this.restApi.get(this.getFindByIdEndpoint(action)) .map((data: DSpaceRESTV2Response) => this.getSerializer().deserialize(data)) .do((t: T) => { - this.cache.add(t, GlobalConfig.cache.msToLive); + this.objectCache.add(t, GlobalConfig.cache.msToLive); }) - .map((t: T) => new DataSuccessAction(action.payload.key, [t.uuid])) - .catch((errorMsg: string) => Observable.of(new DataErrorAction(action.payload.key, errorMsg))); + .map((t: T) => new RequestCacheSuccessAction(action.payload.key, [t.uuid])) + .catch((errorMsg: string) => Observable.of(new RequestCacheErrorAction(action.payload.key, errorMsg))); }); } diff --git a/src/app/core/data-services/data.service.ts b/src/app/core/data-services/data.service.ts index 26a9e4e377..120245c769 100644 --- a/src/app/core/data-services/data.service.ts +++ b/src/app/core/data-services/data.service.ts @@ -1,10 +1,10 @@ import { OpaqueToken } from "@angular/core"; import { Observable } from "rxjs"; import { Store } from "@ngrx/store"; -import { CacheService } from "./cache/cache.service"; -import { CacheableObject } from "./cache/cache.reducer"; -import { DataState } from "./data.reducer"; -import { DataFindAllRequestAction, DataFindByIDRequestAction } from "./data.actions"; +import { ObjectCacheService } from "../cache/object-cache.service"; +import { CacheableObject } from "../cache/object-cache.reducer"; +import { RequestCacheState } from "../cache/request-cache.reducer"; +import { FindAllRequestCacheAction, FindByIDRequestCacheAction } from "../cache/request-cache.actions"; import { ParamHash } from "../shared/param-hash"; import { isNotEmpty } from "../../shared/empty.util"; @@ -12,28 +12,28 @@ export abstract class DataService<T extends CacheableObject> { abstract name: OpaqueToken; constructor( - private store: Store<DataState>, - private cache: CacheService + private store: Store<RequestCacheState>, + private objectCache: ObjectCacheService ) { } findAll(scopeID?: string): Observable<Array<T>> { const key = new ParamHash(this.name, 'findAll', scopeID).toString(); - this.store.dispatch(new DataFindAllRequestAction(key, this.name, scopeID)); + this.store.dispatch(new FindAllRequestCacheAction(key, this.name, scopeID)); //get an observable of the IDs from the store - return this.store.select<Array<string>>('core', 'data', key, 'resourceUUIDs') + return this.store.select<Array<string>>('core', 'cache', 'request', key, 'resourceUUIDs') .flatMap((resourceUUIDs: Array<string>) => { // use those IDs to fetch the actual objects from the cache - return this.cache.getList<T>(resourceUUIDs); + return this.objectCache.getList<T>(resourceUUIDs); }); } findById(id: string): Observable<T> { const key = new ParamHash(this.name, 'findById', id).toString(); - this.store.dispatch(new DataFindByIDRequestAction(key, this.name, id)); - return this.store.select<Array<string>>('core', 'data', key, 'resourceUUIDs') + this.store.dispatch(new FindByIDRequestCacheAction(key, this.name, id)); + return this.store.select<Array<string>>('core', 'cache', 'request', key, 'resourceUUIDs') .flatMap((resourceUUIDs: Array<string>) => { if(isNotEmpty(resourceUUIDs)) { - return this.cache.get<T>(resourceUUIDs[0]); + return this.objectCache.get<T>(resourceUUIDs[0]); } else { return Observable.of(undefined); diff --git a/src/app/core/data-services/item-data.effects.ts b/src/app/core/data-services/item-data.effects.ts index 3976691e48..c1b8fb5ef2 100644 --- a/src/app/core/data-services/item-data.effects.ts +++ b/src/app/core/data-services/item-data.effects.ts @@ -3,10 +3,10 @@ import { DataEffects } from "./data.effects"; import { Serializer } from "../serializer"; import { Item } from "../shared/item.model"; import { DSpaceRESTv2Serializer } from "../dspace-rest-v2/dspace-rest-v2.serializer"; -import { CacheService } from "./cache/cache.service"; +import { ObjectCacheService } from "../cache/object-cache.service"; import { DSpaceRESTv2Service } from "../dspace-rest-v2/dspace-rest-v2.service"; import { Actions, Effect } from "@ngrx/effects"; -import { DataFindAllRequestAction, DataFindByIDRequestAction } from "./data.actions"; +import { FindAllRequestCacheAction, FindByIDRequestCacheAction } from "../cache/request-cache.actions"; import { ItemDataService } from "./item-data.service"; @Injectable() @@ -14,17 +14,17 @@ export class ItemDataEffects extends DataEffects<Item> { constructor( actions$: Actions, restApi: DSpaceRESTv2Service, - cache: CacheService, + cache: ObjectCacheService, dataService: ItemDataService ) { super(actions$, restApi, cache, dataService); } - protected getFindAllEndpoint(action: DataFindAllRequestAction): string { + protected getFindAllEndpoint(action: FindAllRequestCacheAction): string { return '/items'; } - protected getFindByIdEndpoint(action: DataFindByIDRequestAction): string { + protected getFindByIdEndpoint(action: FindByIDRequestCacheAction): string { return `/items/${action.payload.resourceID}`; } diff --git a/src/app/core/data-services/item-data.service.ts b/src/app/core/data-services/item-data.service.ts index 2d7128289a..86b6bf9678 100644 --- a/src/app/core/data-services/item-data.service.ts +++ b/src/app/core/data-services/item-data.service.ts @@ -2,16 +2,16 @@ import { Injectable, OpaqueToken } from "@angular/core"; import { Store } from "@ngrx/store"; import { DataService } from "./data.service"; import { Item } from "../shared/item.model"; -import { CacheService } from "./cache/cache.service"; -import { DataState } from "./data.reducer"; +import { ObjectCacheService } from "../cache/object-cache.service"; +import { RequestCacheState } from "../cache/request-cache.reducer"; @Injectable() export class ItemDataService extends DataService<Item> { name = new OpaqueToken('ItemDataService'); constructor( - store: Store<DataState>, - cache: CacheService + store: Store<RequestCacheState>, + cache: ObjectCacheService ) { super(store, cache); } diff --git a/src/app/core/shared/dspace-object.model.ts b/src/app/core/shared/dspace-object.model.ts index d9197db2b4..4318e6b80e 100644 --- a/src/app/core/shared/dspace-object.model.ts +++ b/src/app/core/shared/dspace-object.model.ts @@ -1,7 +1,7 @@ import { autoserialize, autoserializeAs } from "cerialize"; import { Metadatum } from "./metadatum.model" import { isEmpty, isNotEmpty } from "../../shared/empty.util"; -import { CacheableObject } from "../data-services/cache/cache.reducer"; +import { CacheableObject } from "../cache/object-cache.reducer"; /** * An abstract model class for a DSpaceObject. diff --git a/src/backend/api.ts b/src/backend/api.ts index 1b86548195..bc62629737 100644 --- a/src/backend/api.ts +++ b/src/backend/api.ts @@ -92,7 +92,7 @@ export function createMockApi() { router.route('/collections/:collection_id') .get(function(req, res) { - console.log('GET', util.inspect(req.collection.id, { colors: true })); + // console.log('GET', util.inspect(req.collection.id, { colors: true })); res.json(toHALResponse(req, req.collection)); // }) // .put(function(req, res) { @@ -154,7 +154,7 @@ export function createMockApi() { router.route('/items/:item_id') .get(function(req, res) { - console.log('GET', util.inspect(req.item, { colors: true })); + // console.log('GET', util.inspect(req.item, { colors: true })); res.json(toHALResponse(req, req.item)); // }) // .put(function(req, res) { @@ -199,7 +199,7 @@ export function createMockApi() { router.route('/bundles/:bundle_id') .get(function(req, res) { - console.log('GET', util.inspect(req.bundle, { colors: true })); + // console.log('GET', util.inspect(req.bundle, { colors: true })); res.json(toHALResponse(req, req.bundle)); }); @@ -229,7 +229,7 @@ export function createMockApi() { router.route('/bitstreams/:bitstream_id') .get(function(req, res) { - console.log('GET', util.inspect(req.bitstream, { colors: true })); + // console.log('GET', util.inspect(req.bitstream, { colors: true })); res.json(toHALResponse(req, req.bitstream)); }); -- GitLab