Reputation: 143
Working with Akavache for past couple of days. I have several methods which is using GetAndFetchLatest method but some methods never calls the fetchFunc and the issue is occuring randomly for all functions.
public async Task<ChecklistModel> GetChecklistTypes()
{
var ChecklistTypesCache =
BlobCache.LocalMachine.GetAndFetchLatest("ChecklistTypes",
() => GetChecklistTypesRemote(),
offset =>
{
TimeSpan elapsed = DateTimeOffset.Now - offset;
return elapsed > new TimeSpan(hours: 0, minutes: 5, seconds: 0);
});
ChecklistTypesCache.Subscribe(subsribedData =>
{
_checkilstModel = subsribedData;
});
_checkilstModel = await ChecklistTypesCache.FirstOrDefaultAsync();
return _checkilstModel;
}
public async Task<ChecklistModel> GetChecklistTypesRemote()
{
//do something
}
Anyone faced this issue? Do I need to do something else to work? How to fix this?
public async Task<IEnumerable<ChecklistModel.Checklist>>
GetChecklistTypesCache()
{
IEnumerable<ChecklistModel.Checklist> checklistModel = null;
var ChecklistTypesCache =
BlobCache.LocalMachine.GetAndFetchLatest("ChecklistAccessLevels",
() => GetChecklistTypesRemote(),
offset =>
{
TimeSpan elapsed = DateTimeOffset.Now -
offset;
return elapsed > new TimeSpan(hours: 0,
minutes: 5, seconds: 0);
});
ChecklistTypesCache.Subscribe(subsribedData =>
{
checklistModel = subsribedData;
});
checklistModel = await ChecklistTypesCache.FirstOrDefaultAsync();
return checklistModel;
}
public async Task<IEnumerable<ChecklistModel.Checklist>> GetChecklistTypesRemote()
{
//do something
}
Upvotes: 3
Views: 1071
Reputation: 2177
So to elaborate on what @Geoffrey Huntley said it's a little bit hard to shape a response because the way you're doing it (even in the Gist) doesn't really make sense "Reactively". GetAndFetchLatest doesn't really make any sense to use if you're going to use the promise/async/await patterns... If you're going to use GetAndFetchLatest your code would just look something like
public IObservable<ChecklistModel.Checklist> GetChecklistTypesCache()
{
return BlobCache.LocalMachine.GetAndFetchLatest("ChecklistAccessLevels",
async () =>
{
if (!await Tools.IsConnected()) return null;
return await GetChecklistTypesRemote();
},
offset =>
{
TimeSpan elapsed = DateTimeOffset.Now - offset;
return elapsed > new TimeSpan(hours: 0, minutes: 0, seconds: 30);
});
}
public async Task<ChecklistModel> GetChecklistTypesRemote()
{
//do something
}
//calling code
//Now this is going to possibly fire twice. Once for the cached version
//and then one for the version from the Func
GetChecklistTypesCache().Subscribe(subsribedData =>
{
List<ChecklistModel.Checklist> checklistCollection = new
List<ChecklistModel.Checklist>();
checklistCollection.Clear();
checklistCollection.Add(subsribedData);
checkilstModel = checklistCollection.ToObservable();
});
If you want to use async/await then you'd need to just use the Akavache parts that only return one result
These are all taken from the samples on the github page https://github.com/akavache/Akavache
So first you'd try to get your thing from the cache
try {
toaster = await BlobCache.LocalMachine.GetObjectAsync("ChecklistAccessLevels");
} catch (KeyNotFoundException) {
}
If it's not there then you'd call your func
if(toaster == null)
toaster = await GetChecklistTypesRemote()
Now you'd insert it into the cache
await BlobCache.LocalMachine.InsertObject("ChecklistAccessLevels", toaster );
But maybe "GetOrFetchObject" would work better for your purpose as it will only fire once and will work with a task? But it's a little hard to shape a response because i'm still not quite clear the use case. I think reading through the https://reactiveui.net/concepts would be useful and once the Reactive concepts take hold a bit more the interactions will make more sense.
Upvotes: 3
Reputation: 506
GetAndFetchLatest returns multiple times. It's designed to be used with the Reactive Extensions as an observable that you subscribe to. The promise/async/await pattern only returns once. Rx is 9+ years old now and well worth learning - see https://reactiveui.net/concepts
Upvotes: 4