Last active
March 26, 2017 00:09
-
-
Save MaksTuev/59c244d1bb0fc78e7f681e26a05efccc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.avs.express.android.interactor.common; | |
/** | |
* Базовый класс репозитория | |
*/ | |
public class BaseRepository { | |
private ConnectionQualityProvider connectionQualityProvider; | |
public BaseRepository(ConnectionQualityProvider connectionQualityProvider) { | |
this.connectionQualityProvider = connectionQualityProvider; | |
} | |
/** | |
* Действия при смене пользователя | |
*/ | |
public void onSessionChanged() { | |
} | |
/** | |
* Осуществляет гибридный запрос, в методе происходит объединение данных приходящих с сервера и из кеша | |
* | |
* @param priority указывает из какого источника данные должны эмитится в результирующий | |
* Observable в первую очередь | |
* @param cacheRequest запрос к кешу | |
* @param networkRequestCreator функция, которая должна вернуть запрос к серверу, | |
* Integer параметр этой функции определяет {@link ServerConstants.QueryMode} | |
* @param <T> тип возвращаемого значения | |
*/ | |
protected <T> Observable<T> hybridQuery(DataPriority priority, | |
Observable<T> cacheRequest, | |
Func1<Integer, Observable<T>> networkRequestCreator) { | |
return cacheRequest | |
//оборачиваем ошибку получения кеша чтобы обработать ее в конце чейна | |
.onErrorResumeNext(e -> Observable.error(new CacheExceptionWrapper(e))) | |
.flatMap(cache -> { | |
boolean cacheExist = cache != null; | |
@ServerConstants.QueryMode int queryMode = cacheExist | |
? QUERY_MODE_ONLY_IF_CHANGED | |
: QUERY_MODE_FORCE; | |
boolean cacheFirst = priority == DataPriority.AUTO | |
? !connectionQualityProvider.isConnectedFast() | |
: priority == DataPriority.CACHE; | |
Observable<T> cacheResultObservable = cacheExist ? Observable.just(cache) : Observable.empty(); | |
Observable<T> networkRequestObservable = networkRequestCreator.call(queryMode); | |
if (cacheFirst) { | |
return Observable.concat( | |
cacheResultObservable, | |
networkRequestObservable.onErrorResumeNext( | |
this::processNetworkException)); | |
} else { | |
return networkRequestObservable.onErrorResumeNext(e -> | |
Observable.concat( | |
cacheResultObservable, | |
processNetworkException(e))); | |
} | |
}) | |
.onErrorResumeNext(e -> { | |
if(e instanceof CacheExceptionWrapper) { | |
//в случае ошибки получения данных из кеша производим запрос на сервер | |
Logger.e(e.getCause(), "Error when getting data from cache"); | |
return networkRequestCreator.call(QUERY_MODE_FORCE); | |
} else { | |
return Observable.error(e); | |
} | |
}); | |
} | |
protected <T> Observable<T> hybridQuery(Observable<T> cacheRequest, | |
Func1<Integer, Observable<T>> networkRequestCreator) { | |
return hybridQuery(DataPriority.AUTO, cacheRequest, networkRequestCreator); | |
} | |
/** | |
* Осуществляет гибридный запрос, в методе происходит объединение данных приходящих с сервера и из кеша | |
* | |
* @param requestCreator функция, которая должна вернуть запрос к серверу, поддерживающий механизм простого кеширования | |
* Integer параметр этой функции определяет {@link ServerConstants.QueryMode} | |
* @param <T> тип ответа сервера | |
*/ | |
protected <T extends BaseResponse> Observable<T> hybridQueryWithSimpleCache(DataPriority priority, | |
Func1<Integer, Observable<T>> requestCreator) { | |
return hybridQuery(priority, requestCreator.call(QUERY_MODE_FROM_SIMPLE_CACHE), requestCreator); | |
} | |
protected <T extends BaseResponse> Observable<T> hybridQueryWithSimpleCache(Func1<Integer, Observable<T>> requestCreator) { | |
return hybridQueryWithSimpleCache(DataPriority.AUTO, requestCreator); | |
} | |
private <T> Observable<T> processNetworkException(Throwable e) { | |
return e instanceof NotModifiedException | |
? Observable.empty() | |
: Observable.error(e); | |
} | |
/** | |
* оборачивает ошибку получения данных из кеша | |
*/ | |
private class CacheExceptionWrapper extends Exception { | |
public CacheExceptionWrapper(Throwable cause) { | |
super(cause); | |
} | |
} | |
} | |
//------------------- | |
public enum DataPriority { | |
CACHE, | |
SERVER, | |
AUTO | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment