Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
public static IObservable<KarmaModel> GetKarma(string userName) {
return Observable.Create<KarmaModel>(observer =>
Scheduler.Schedule(async () => {
var karmaResponse = await HttpClient.Get(userName);
if (!karmaResponse.IsSuccessful) {
observer.OnError(karmaResponse.Exception);
} else {
observer.OnNext(karmaResponse.Data);
observer.OnCompleted();
}
})
);
}
public static IObservable<KarmaModel> Cache(this IObservable<KarmaModel> source, ICache cache, string userName) {
return Observable.CreateWithDisposable<KarmaModel>(observer =>
// Provide value from cache immediately if exists.
KarmaMode karma = null;
if (cache.HasCached(userName)) {
karma = cache.GetCachedItem(userName);
observer.OnNext(karma);
}
// Then just forward values to observer, caching last value.
source.Subscribe(
(karma) => {
if (karma != null && updatedKarma.LastModified > karma.LastModified) {
cache.Put(updatedKarma)
observer.OnNext(karma)
}
},
observer.OnError,
observer.OnCompleted
);
);
}
public interface ICache {
bool Empty();
KarmaModel Get();
void Put(KarmaModel);
}
public static IObservable<KarmaModel> Cache(this IObservable<KarmaModel> source, ICache cache) {
// Изменения очевидны
}
var userName = "foo";
var userCache = globalCache.getByKey(userName);
var karma = new GetKarma(userName).Cache(userCache).DistinctUntilChanged(new KarmaLastModifiedComparator)
bla-bla.Cache(new ICache { Karma Get() { return cache.Get(userName); }; void Put(Karma karma) { cache.Put(userName, karma); ... })
.WithCache получился даже generic и не зависящий от ICache. Пожалуй так даже и лучше. public static IObservable<T> WithCache<T>(this IObservable<T> source,
Func<T> get,
Action<T> put) where T : class
{
return Observable.Create<T>(observer =>
{
var cached = get();
if (cached != null)
{
observer.OnNext(cached);
}
source.Subscribe(item =>
{
put(item);
observer.OnNext(item);
observer.OnCompleted();
}, observer.OnError);
return Disposable.Empty;
});
}
.WithCache(() => Cache.GetCachedItem(userName), model => Cache.Put(model))public interface ICache
{
bool HasCached(string key);
BaseModel GetCachedItem(string key);
void Put(BaseModel updatedModel);
}
public abstract BaseModel
{
public string Key { get; set; }
}
public KarmaModel : BaseModel
{
// ...
}
Reactive Extensions: клиент для условного api со стратегией Cache-Aside & Refresh-Ahead