Files
dspace-angular/src/app/core/cache/response-cache.service.ts
2018-09-14 09:26:30 +02:00

101 lines
2.9 KiB
TypeScript

import { filter, take, distinctUntilChanged, first } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { MemoizedSelector, select, Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { ResponseCacheEntry } from './response-cache.reducer';
import { hasNoValue } from '../../shared/empty.util';
import { ResponseCacheRemoveAction, ResponseCacheAddAction } from './response-cache.actions';
import { RestResponse } from './response-cache.models';
import { coreSelector, CoreState } from '../core.reducers';
import { pathSelector } from '../shared/selectors';
function entryFromKeySelector(key: string): MemoizedSelector<CoreState, ResponseCacheEntry> {
return pathSelector<CoreState, ResponseCacheEntry>(coreSelector, 'cache/response', key);
}
/**
* A service to interact with the response cache
*/
@Injectable()
export class ResponseCacheService {
constructor(
private store: Store<CoreState>
) {
}
add(key: string, response: RestResponse, msToLive: number): Observable<ResponseCacheEntry> {
if (!this.has(key)) {
this.store.dispatch(new ResponseCacheAddAction(key, response, new Date().getTime(), msToLive));
}
return this.get(key);
}
/**
* Get an observable of the response with the specified key
*
* @param key
* the key of the response to get
* @return Observable<ResponseCacheEntry>
* an observable of the ResponseCacheEntry with the specified key
*/
get(key: string): Observable<ResponseCacheEntry> {
return this.store.pipe(
select(entryFromKeySelector(key)),
filter((entry: ResponseCacheEntry) => this.isValid(entry)),
distinctUntilChanged()
)
}
/**
* Check whether the response with the specified key is cached
*
* @param key
* the key of the response to check
* @return boolean
* true if the response with the specified key is cached,
* false otherwise
*/
has(key: string): boolean {
let result: boolean;
this.store.pipe(select(entryFromKeySelector(key)),
first()
).subscribe((entry: ResponseCacheEntry) => {
result = this.isValid(entry);
});
return result;
}
remove(key: string): void {
if (this.has(key)) {
this.store.dispatch(new ResponseCacheRemoveAction(key));
}
}
/**
* Check whether a ResponseCacheEntry should still be cached
*
* @param entry
* the entry to check
* @return boolean
* false if the entry is null, undefined, or its time to
* live has been exceeded, true otherwise
*/
private isValid(entry: ResponseCacheEntry): boolean {
if (hasNoValue(entry)) {
return false;
} else {
const timeOutdated = entry.timeAdded + entry.msToLive;
const isOutDated = new Date().getTime() > timeOutdated;
if (isOutDated) {
this.store.dispatch(new ResponseCacheRemoveAction(entry.key));
}
return !isOutDated;
}
}
}