Giter VIP home page Giter VIP logo

reactiveui / akavache Goto Github PK

View Code? Open in Web Editor NEW
2.4K 108.0 289.0 78.59 MB

An asynchronous, persistent key-value store created for writing desktop and mobile applications, based on SQLite3. Akavache is great for both storing important data as well as cached local data that expires.

Home Page: https://evolve.xamarin.com/session/56e2044afd00c0253cae33a3

License: MIT License

C# 100.00%
c-sharp cache reactive-extensions reactive-programming xamarin dotnet akavache cross-platform

akavache's Introduction

NuGet Stats Build Code Coverage

Akavache

Akavache: An Asynchronous Key-Value Store for Native Applications

Akavache is an asynchronous, persistent (i.e. writes to disk) key-value store created for writing desktop and mobile applications in C#, based on SQLite3. Akavache is great for both storing important data (i.e. user settings) as well as cached local data that expires.

Where can I use it?

Akavache is currently compatible with:

  • Xamarin.iOS / Xamarin.Mac / Xamarin.Android / Xamarin.TVOS / Xamarin.WatchOS
  • Maui iOS / Mac / Mac Catalyst / Android / TVOS
  • .NET 4.6.2 (and above) and .NET 6 Desktop (WPF and WinForms)
  • .NET 6.0
  • Windows 10 (Universal Windows Platform)
  • Tizen 4.0

What does that mean?

Downloading and storing remote data from the internet while still keeping the UI responsive is a task that nearly every modern application needs to do. However, many applications that don't take the consideration of caching into the design from the start often end up with inconsistent, duplicated code for caching different types of objects.

Akavache is a library that makes common app patterns easy, and unifies caching of different object types (i.e. HTTP responses vs. JSON objects vs. images).

It's built on a core key-value byte array store (conceptually similar to a Dictionary<string, byte[]>), and on top of that store, extensions are added to support:

  • Arbitrary objects via JSON.NET
  • Fetching and loading Images and URLs from the Internet
  • Storing and automatically encrypting User Credentials

Contents

Getting Started

Interacting with Akavache is primarily done through an object called BlobCache. At App startup, you must first set your app's name via BlobCache.ApplicationName or Akavache.Registrations.Start("ApplicationName") . After setting your app's name, you're ready to save some data.

For example with Xamarin Forms or WPF applications you'll place this in the constructor of your App.xaml.cs file.

Choose a location

There are four built-in locations that have some magic applied on some systems:

  • BlobCache.LocalMachine - Cached data. This data may get deleted without notification.
  • BlobCache.UserAccount - User settings. Some systems backup this data to the cloud.
  • BlobCache.Secure - For saving sensitive data - like credentials.
  • BlobCache.InMemory - A database, kept in memory. The data is stored for the lifetime of the app.

The magic

  • Xamarin.iOS may remove data, stored in BlobCache.LocalMachine, to free up disk space (only if your app is not running). The locations BlobCache.UserAccount and BlobCache.Secure will be backed up to iCloud and iTunes. Apple Documentation
  • Xamarin.Android may also start deleting data, stored in BlobCache.LocalMachine, if the system runs out of disk space. It isn't clearly specified if your app could be running while the system is cleaning this up. Android Documentation
  • Windows 10 (UWP) will replicate BlobCache.UserAccount and BlobCache.Secure to the cloud and synchronize it to all user devices on which the app is installed UWP Documentation

Platform-specific notes

  • Windows 10 (Universal Windows Platform) - You must mark your application as x86 or ARM, or else you will get a strange runtime error about SQLitePCL_Raw not loading correctly. You must also ensure that the Microsoft Visual C++ runtime is added to your project.

Handling Xamarin/Maui Linker

There are two options to ensure the Akavache.Sqlite3 dll will not be removed by Xamarin and Maui build tools

1) Add a file to reference the types

public static class LinkerPreserve
{
  static LinkerPreserve()
  {
    var persistentName = typeof(SQLitePersistentBlobCache).FullName;
    var encryptedName = typeof(SQLiteEncryptedBlobCache).FullName;
  }
}

2) Use the following initializer in your cross platform library or in your head project

Akavache.Registrations.Start("ApplicationName")

Using Akavache

The most straightforward way to use Akavache is via the object extensions:

using System.Reactive.Linq;   // IMPORTANT - this makes await work!

// Make sure you set the application name before doing any inserts or gets
Akavache.Registrations.Start("AkavacheExperiment")

var myToaster = new Toaster();
await BlobCache.UserAccount.InsertObject("toaster", myToaster);

//
// ...later, in another part of town...
//

// Using async/await
var toaster = await BlobCache.UserAccount.GetObject<Toaster>("toaster");

// or without async/await
Toaster toaster;

BlobCache.UserAccount.GetObject<Toaster>("toaster")
    .Subscribe(x => toaster = x, ex => Console.WriteLine("No Key!"));

Handling Errors

When a key is not present in the cache, GetObject throws a KeyNotFoundException (or more correctly, OnError's the IObservable). Often, you would want to return a default value instead of failing:

Toaster toaster;

try {
    toaster = await BlobCache.UserAccount.GetObject("toaster");
} catch (KeyNotFoundException ex) {
    toaster = new Toaster();
}

// Or without async/await:
toaster = await BlobCache.UserAccount.GetObject<Toaster>("toaster")
    .Catch(Observable.Return(new Toaster()));

Shutting Down

Critical to the integrity of your Akavache cache is the BlobCache.Shutdown() method. You must call this when your application shuts down. Moreover, be sure to wait for the result:

BlobCache.Shutdown().Wait();

Failure to do this may mean that queued items are not flushed to the cache.

Using a different SQLitePCL.raw bundle

To use a different SQLitePCL.raw bundle, e.g. Microsoft.AppCenter:

  • Install the akavache.sqlite3 nuget instead of akavache
  • Install the SQLitePCLRaw bundle you want to use, e.g., SQLitePCLRaw.bundle_green
  • Use Akavache.Sqlite3.Registrations.Start("ApplicationName", () => SQLitePCL.Batteries_V2.Init()); in your platform projects or in your cross platform project.
<PackageReference Include="akavache.sqlite3" Version="6.0.40-g7e90c572c6" />
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="1.1.11" />
Akavache.Sqlite3.Registrations.Start("ApplicationName", () => SQLitePCL.Batteries_V2.Init());

For more info about using your own versions of SqlitePCL.raw

Examining Akavache caches

Using Akavache Explorer, you can dig into Akavache repos for debugging purposes to see what has been stored.

What's this Global Variable nonsense?

Why can't I use $FAVORITE_IOC_LIBRARY?

You totally can. Just instantiate SQLitePersistentBlobCache or SQLiteEncryptedBlobCache instead - the static variables are there just to make it easier to get started.

DateTime/DateTimeOffset Considerations

Our default implementation overrides BSON to read and write DateTime's as UTC. To override the reader's behavior you can set BlobCache.ForcedDateTimeKind as in the following example:

// Sets the reader to return DateTime/DateTimeOffset in Local.
BlobCache.ForcedDateTimeKind = DateTimeKind.Local;

DateTime are stored as ticks for high precision. DateTimeOffset are stored as ticks for both the Date/Time aspect and the offset.

Basic Method Documentation

Every blob cache supports the basic raw operations given below (some of them are not implemented directly, but are added on via extension methods):

/*
 * Get items from the store
 */

// Get a single item
IObservable<byte[]> Get(string key);

// Get a list of items
IObservable<IDictionary<string, byte[]>> Get(IEnumerable<string> keys);

// Get an object serialized via InsertObject
IObservable<T> GetObject<T>(string key);

// Get all objects of type T
IObservable<IEnumerable<T>> GetAllObjects<T>();

// Get a list of objects given a list of keys
IObservable<IDictionary<string, T>> GetObjects<T>(IEnumerable<string> keys);

/*
 * Save items to the store
 */

// Insert a single item
IObservable<Unit> Insert(string key, byte[] data, DateTimeOffset? absoluteExpiration = null);

// Insert a set of items
IObservable<Unit> Insert(IDictionary<string, byte[]> keyValuePairs, DateTimeOffset? absoluteExpiration = null);

// Insert a single object
IObservable<Unit> InsertObject<T>(string key, T value, DateTimeOffset? absoluteExpiration = null);

// Insert a group of objects
IObservable<Unit> InsertObjects<T>(IDictionary<string, T> keyValuePairs, DateTimeOffset? absoluteExpiration = null);

/*
 * Remove items from the store
 */

// Delete a single item
IObservable<Unit> Invalidate(string key);

// Delete a list of items
IObservable<Unit> Invalidate(IEnumerable<string> keys);

// Delete a single object (do *not* use Invalidate for items inserted with InsertObject!)
IObservable<Unit> InvalidateObject<T>(string key);

// Deletes a list of objects
IObservable<Unit> InvalidateObjects<T>(IEnumerable<string> keys);

// Deletes all items (regardless if they are objects or not)
IObservable<Unit> InvalidateAll();

// Deletes all objects of type T
IObservable<Unit> InvalidateAllObjects<T>();

/*
 * Get Metadata about items
 */

// Return a list of all keys. Use for debugging purposes only.
IObservable<IEnumerable<string>> GetAllKeys();

// Return the time which an item was created
IObservable<DateTimeOffset?> GetCreatedAt(string key);

// Return the time which an object of type T was created
IObservable<DateTimeOffset?> GetObjectCreatedAt<T>(string key);

// Return the time which a list of keys were created
IObservable<IDictionary<string, DateTimeOffset?>> GetCreatedAt(IEnumerable<string> keys);

/*
 * Utility methods
 */

// Attempt to ensure all outstanding operations are written to disk
IObservable<Unit> Flush();

// Preemptively drop all expired keys and run SQLite's VACUUM method on the
// underlying database
IObservable<Unit> Vacuum();

Extension Method Documentation

On top of every IBlobCache object, there are extension methods that help with common application scenarios:

/*
 * Username / Login Methods (only available on ISecureBlobCache)
 */

// Save login information for the given host
IObservable<Unit> SaveLogin(string user, string password, string host = "default", DateTimeOffset? absoluteExpiration = null);

// Load information for the given host
IObservable<LoginInfo> GetLoginAsync(string host = "default");

// Erase information for the given host
IObservable<Unit> EraseLogin(string host = "default");

/*
 * Downloading and caching URLs and Images
 */

// Download a file as a byte array
IObservable<byte[]> DownloadUrl(string url,
    IDictionary<string, string> headers = null,
    bool fetchAlways = false,
    DateTimeOffset? absoluteExpiration = null);

// Load a given key as an image
IObservable<IBitmap> LoadImage(string key, float? desiredWidth = null, float? desiredHeight = null);

// Download an image from the network and load it
IObservable<IBitmap> LoadImageFromUrl(string url,
    bool fetchAlways = false,
    float? desiredWidth = null,
    float? desiredHeight = null,
    DateTimeOffset? absoluteExpiration = null);

/*
 * Composite operations
 */

// Attempt to return an object from the cache. If the item doesn't
// exist or returns an error, call a Func to return the latest
// version of an object and insert the result in the cache.
IObservable<T> GetOrFetchObject<T>(string key, Func<Task<T>> fetchFunc, DateTimeOffset? absoluteExpiration = null);

// Like GetOrFetchObject, but isn't async
IObservable<T> GetOrCreateObject<T>(string key, Func<T> fetchFunc, DateTimeOffset? absoluteExpiration = null);

// Immediately return a cached version of an object if available, but *always*
// also execute fetchFunc to retrieve the latest version of an object.
IObservable<T> GetAndFetchLatest<T>(this IBlobCache This,
    string key,
    Func<IObservable<T>> fetchFunc,
    Func<DateTimeOffset, bool> fetchPredicate = null,
    DateTimeOffset? absoluteExpiration = null,
    bool shouldInvalidateOnError = false,
    Func<T, bool> cacheValidationPredicate = null)

akavache's People

Contributors

anaisbetts avatar aroben avatar chrispulman avatar dependabot-preview[bot] avatar dependabot[bot] avatar ericsink avatar erik-hooper avatar flagbug avatar ghuntley avatar glennawatson avatar haacked avatar jcomtois avatar jlaanstra avatar jploo avatar kmgallahan avatar mms- avatar ncruces avatar nigel-sampson avatar niik avatar nwestfall avatar petegoo avatar pureween avatar renovate[bot] avatar rlittlesii avatar shiftbot avatar shiftkey avatar softlion avatar tclem avatar trmcnvn avatar worldbeater avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

akavache's Issues

3.0.2 Akavache.BlobCache constructor throws Exception

When trying to use BlobCache.ApplicationName = "blah" as per the readme an exception is thrown from the static constructor as the TaskPoolScheduler is being used and it has been replaced with Scheduler.Default in the latest RXExtensions

Error activating IFilesystemProvider?

Is it a true issue or you just missed to put this on the readme doc?
I've already overcame this but, is it realy necessary to bind the SimpleFilesystemProvider to the
IFilesystemProvider?

Error Creating a PersistentBlobCache on WP

When attempting to create an instance of a PersistentBlobCache an IO Access error gets thrown. Seems like its being caused by the static properties that are Lazy loaded - https://github.com/github/Akavache/blob/master/Akavache/PersistentBlobCache.cs#L87

Environment:
Windows 8
Windows Phone 7.1.1 tools
Akavache NuGet package (v1.0.1)
Same result on both Device and Emulator

My code: https://gist.github.com/2656520
The stack trace: http://pastebin.com/dsBtSJzS

System.Collections.Concurrent conflict

Akavache/ConcurrentDictionary.cs

Because this declares the namespace System.Collections.Concurrent it conflicts with another package (System.Threading.Tasks) in Silverlight 5

Any way to change the name or mark it as internal?

Nevermind..I forgot about extern alias.

Could not open database file: BlobCache/userblobs.db (CannotOpen)

When debugging on device.

Now using
BlobCache.ApplicationName = "Doggity";
BlobCache.EnsureInitialized();
BlobCache.UserAccount.GetObjectAsync<Venue[]>("Venues");

which returns an error on the GetObjectAsync line. Do i need to grant extra permissions? External storage is already granted.

BlobCache.ApplicationName = "Doggity";
BlobCache.EnsureInitialized();

04-03 11:29:19.907 E/SQLiteLog(32234): (14) cannot open file at line 30191 of [00bb9c9ce4]
04-03 11:29:19.907 E/SQLiteLog(32234): (14) os_unix.c:30191: (2) open(//BlobCache/userblobs.db)

Error: Could not open database file

i am opening/creating the DB on android like so

  Store = new SqlitePersistentBlobCache("Doggity");

and get the stacktrace below.

With standard sqlite there is an OpenOrCreate method - do i need some equivalent here?

System.TypeInitializationException: An exception was thrown by the type initializer for Doggity.Android.AndroidConfig
04-02 22:52:18.924 E/mono    (23754): 
04-02 22:52:18.924 E/mono    (23754): Unhandled Exception:
04-02 22:52:18.924 E/mono    (23754): System.TypeInitializationException: An exception was thrown by the type initializer for Doggity.Android.AndroidConfig ---> SQLite.SQLiteException: Could not open database file: Doggity (CannotOpen)
04-02 22:52:18.924 E/mono    (23754):   at SQLite.SQLiteConnection..ctor (System.String databasePath, SQLiteOpenFlags openFlags, Boolean storeDateTimeAsTicks) [0x0006d] in /Users/paul/github/Akavache/Akavache.Sqlite3/SQLite.cs:125 
04-02 22:52:18.924 E/mono    (23754):   at SQLite.SQLiteConnectionWithoutLock..ctor (SQLite.SQLiteConnectionString connectionString, SQLiteOpenFlags flags) [0x00000] in /Users/paul/github/Akavache/Akavache.Sqlite3/SQLiteAsync.cs:344 
04-02 22:52:18.924 E/mono    (23754):   at SQLite.SQLiteConnectionPool+Entry..ctor (SQLite.SQLiteConnectionString connectionString, SQLiteOpenFlags flags) [0x0000d] in /Users/paul/github/Akavache/Akavache.Sqlite3/SQLiteAsync.cs:330 
04-02 22:52:18.924 E/mono    (23754):   at SQLite.SQLiteConnectionPool+<Reset>c__AnonStorey14.<>m__25 (Int32 _) [0x00000] in /Users/paul/github/Akavache/Akavache.Sqlite3/SQLiteAsync.cs:309 
04-02 22:52:18.924 E/mono    (23754):   at System.Linq.Enumerable+<CreateSelectIterator>c__Iterator10`2[
04-02 22:52:18.927 E/mono-rt (23754): [ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: An exception was thrown by the type initializer for Doggity.Android.AndroidConfig ---> SQLite.SQLiteException: Could not open database file: Doggity (CannotOpen)
04-02 22:52:18.927 E/mono-rt (23754):   at SQLite.SQLiteConnection..ctor (System.String databasePath, SQLiteOpenFlags openFlags, Boolean storeDateTimeAsTicks) [0x0006d] in /Users/paul/github/Akavache/Akavache.Sqlite3/SQLite.cs:125 
04-02 22:52:18.927 E/mono-rt (23754):   at SQLite.SQLiteConnectionWithoutLock..ctor (SQLite.SQLiteConnectionString connectionString, SQLiteOpenFlags flags) [0x00000] in /Users/paul/github/Akavache/Akavache.Sqlite3/SQLiteAsync.cs:344 
04-02 22:52:18.927 E/mono-rt (23754):   at SQLite.SQLiteConnectionPool+Entry..ctor (SQLite.SQLiteConnectionString connectionString, SQLiteOpenFlags flags) [0x0000d] in /Users/paul/github/Akavache/Akavache.Sqlite3/SQLiteAsync.cs:330 
04-02 22:52:18.927 E/mono-rt (23754):   at SQLite.SQLiteConnectionPool+<Reset>c__AnonStorey14.<>m__25 (Int32 _) [0x00000] in /Users/paul/github/Akavache/Akavache.Sqlite3/SQLiteAsync.cs:309 
04-02 22:52:18.927 E/mono-rt (23754):   at System.Linq.Enumerable+<CreateSelectIterator>c__

Potential race condition with Dispose

I wrote up a description of the race condition here: ce9c8a7

This is so difficult to get right. This gives me an idea though. This is a general pattern when multithreading is involved. Maybe we need a special Disposer class that encapsulates this pattern.

You create it and each method becomes wrapped by it.

public void SomeMethod() {
  disposer.Do(() => {/* actual implementation */});
}

public void Dispose() {
   disposer.Dispose(() => { /* actual implementation */});
}

Disposer makes sure that dispose waits on any outstanding operations before it disposes. It also make sure that no new operations can start while disposing. When disposing is done, all operations throw ObjectDisposedException. I think this would be broadly useful. What do you think? If you like it, I can sketch it out in the context of Akavache.

Fixture tests sometime fail because cache hasn't finished writing to disk

Sometimes when I run the Akavache tests I see failures like this:

Test 'Akavache.Tests.PersistentBlobCacheInterfaceFixture.CacheShouldBeRoundtrippable' failed: System.IO.IOException : The process cannot access the file 'C:\Users\Adam Roben\Documents\GitHub\Windows\Akavache\Akavache.Tests\bin\Debug\f4d14bf2-deb3-45d4-9457-f376ab69d3ea\1356c67d7ad1638d816bfb822dd2c25d' because it is being used by another process.
    at System.Reactive.ExceptionHelpers.Throw[T](Exception exception)
    at System.Reactive.Linq.Observable.FirstOrDefaultInternal[TSource](IObservable`1 source, Boolean throwOnEmpty)
    at System.Reactive.Linq.Observable.First[TSource](IObservable`1 source)
    BlobCacheFixture.cs(65,0): at Akavache.Tests.BlobCacheInterfaceFixture.CacheShouldBeRoundtrippable()

Test 'Akavache.Tests.EncryptedBlobCacheInterfaceFixture.CacheShouldBeRoundtrippable' failed: System.IO.IOException : The process cannot access the file 'C:\Users\Adam Roben\Documents\GitHub\Windows\Akavache\Akavache.Tests\bin\Debug\f901b928-26f0-474a-8408-bb9311450866\1356c67d7ad1638d816bfb822dd2c25d' because it is being used by another process.
    at System.Reactive.ExceptionHelpers.Throw[T](Exception exception)
    at System.Reactive.Linq.Observable.FirstOrDefaultInternal[TSource](IObservable`1 source, Boolean throwOnEmpty)
    at System.Reactive.Linq.Observable.First[TSource](IObservable`1 source)
    BlobCacheFixture.cs(65,0): at Akavache.Tests.BlobCacheInterfaceFixture.CacheShouldBeRoundtrippable()

It looks like the cache gets flushed to disk asynchronously and that these tests aren't waiting for it to complete before trying to use the cache files again.

Shouldn't IBlobCache.GetCreatedAt return Observable.Empty or a KeyNotFoundException?

When I call IBlobCache.GetCreatedAt with a key that doesn't exist, I get an observable sequence with one null value. That's counter intuitive. For example, when I call IBlobCache.GetAsync with a key that doesn't exist, I get an observed KeyNotFoundException.

For GetCreatedAt I would have expected one of these behaviors.

This brings up a general question about Rx operators. When you have an operator that returns a single result, when should you return Observable.Return(null) and when should you do Observable.Empty()? I'm finding that the lack of consistency with this leads me to have to write extra defensive boiler-plate code since I'm never sure what any given operator will do.

Thoughts?

Transactions + Cloud Sync

Akavache 3.0's Next Level Feature: Sync

Right now, syncing between a cloud-based data store and a local-based store is Hardβ„’. One of the features I've been thinking about for some time now is adding Akavache backends that represent non-disk stores, such as GDrive or Dropbox Sync.

Right now, dealing with trying to cache data locally, then eventually push it up to The Cloudβ„’ from a desktop or mobile application doesn't have any great solutions. Dropbox Sync attempts to solve some of these problems, but it's pretty thoroughly tied to Dropbox (of course). It also thinks at the level of files, which isn't necessarily very convenient for app developers.

So, basically, Akavache should have a backend that is a "multi-level" backend - a sync cache that itself has an IBlobCache, which represents the local cache for the data. It handles sending data back and forth to The Cloud (perhaps via an IRemoteBlobCache interface), and handles syncing between the two.

API Changes: Transactions

To do this though, Akavache needs to be savvy about transactions. Being able to create a transaction, change several key/value pairs, and either commit them or roll them back atomically is a key part to being able to pull off the cloud sync. Something like:

using (var transaction = cache.BeginTransaction()) {
    cache.InsertObject("foo", bar, transaction);
    cache.InsertObject("baz", bamf, transaction);
};

Cache Locations For Monotouch

The current implimention that uses IsolatedStorageFile saves all caches to the ~/Documents directory on Monotouch.

There are some undesired effects when using the ~/Documents directory. First off everything in this directory is made available to the user through iTunes. Secondly, anything in this directory is backed up to iCloud.

The proper directory for a cache is ~/Library/Caches/ on the iPhone. This directory isn't backed up and is meant for anything that can be easily recreated.

http://docs.xamarin.com/guides/ios/application_fundamentals/working_with_the_file_system#3.2.application-directories

At the very least the argument could be made that the UserAccount cache should be stored in ~/Library/ which is backed up and the LocalMachine should be stored in ~/Library/Caches/ since there is a higher probability that anything stored in the LocalMachine is data that can easily be recreated if necessary and probably doesn't related to user preferences that they might configure in the application.

If you are agreeable on this I can submit a PR.

Can't add Akavache NuGet package to MonoTouch / Xamarin.iOS project

Hey there,

I just tried adding Akavache to an empty/new universal iOS project in VS (with Xamarin's toolchain installed) and unfortunately it failed because the Newtonsoft.Json package does not support MonoTouch projects.. apparently:

Attempting to resolve dependency 'akavache.portable (= 3.0.1)'. Attempting to resolve dependency 'Newtonsoft.Json (β‰₯ 5.0.5)'. Attempting to resolve dependency 'reactiveui-core (β‰₯ 5.0.1)'. Attempting to resolve dependency 'Rx-Main (β‰₯ 2.1.30214.0)'. Attempting to resolve dependency 'Rx-Interfaces (β‰₯ 2.1.30214.0)'. Attempting to resolve dependency 'Rx-Core (β‰₯ 2.1.30214.0)'. Attempting to resolve dependency 'Rx-Linq (β‰₯ 2.1.30214.0)'. Attempting to resolve dependency 'Rx-PlatformServices (β‰₯ 2.1.30214.0)'. Installing 'Newtonsoft.Json 5.0.6'. Successfully installed 'Newtonsoft.Json 5.0.6'. Installing 'Rx-Interfaces 2.1.30214.0'. Successfully installed 'Rx-Interfaces 2.1.30214.0'. Installing 'Rx-Core 2.1.30214.0'. Successfully installed 'Rx-Core 2.1.30214.0'. Installing 'Rx-Linq 2.1.30214.0'. Successfully installed 'Rx-Linq 2.1.30214.0'. Installing 'Rx-PlatformServices 2.1.30214.0'. Successfully installed 'Rx-PlatformServices 2.1.30214.0'. Installing 'Rx-Main 2.1.30214.0'. Successfully installed 'Rx-Main 2.1.30214.0'. Installing 'reactiveui-core 5.0.2'. Successfully installed 'reactiveui-core 5.0.2'. Executing script file 'D:\Development\HelloWorld_App1\packages\reactiveui-core.5.0.2\tools\init.ps1'. Installing 'akavache.portable 3.0.1'. Successfully installed 'akavache.portable 3.0.1'. Installing 'akavache 3.0.1'. Successfully installed 'akavache 3.0.1'. Adding 'Newtonsoft.Json 5.0.6' to HelloWorld_App1. Uninstalling 'Newtonsoft.Json 5.0.6'. Successfully uninstalled 'Newtonsoft.Json 5.0.6'. Install failed. Rolling back... Could not install package 'Newtonsoft.Json 5.0.6'. You are trying to install this package into a project that targets 'MonoTouch,Version=v4.0', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

As MonoTouch is mentioned/targeted in Akavache's nuspec file I was wondering.. what am I doing wrong / what version of Json.Net would be the correct one?

(also: the same goes for ReactiveUI).

Cheers
-JΓΆrg

Problems installing via nuget

I can't get akavache to install in my Windows Phone 8.1 (WinRT) project:

> install-package akavache
> ... successful dependencies...
> Uninstalling 'Splat 1.0.0'.
> Successfully uninstalled 'Splat 1.0.0'.
> Install failed. Rolling back...
> install-package : Could not install package 'Splat 1.0.0'. You are trying to install this package into a project that targets 'WindowsPhoneApp,Version=v8.1', but 
> the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

Trying again with the -pre flag does appear to work, and I see a reference to 3.99.1-beta in my packages.config, but no dependencies are installed, nothing seems to be referenced, and there appears to be no assembly with the Akavache namespace in the project, BlobCache doesn't exist, etc.

WP8 BackgroundAgent Invalid cross-thread access

Windows Phone 8 project
Akavache v3.2.0

Attempting to access the default LocalMachine BlobCache from a WP8 background agent throws UnauthorizedAccessException.
Looks like the exception is coming from ReactiveUI.RxApp when it is not run on a UI thread.

I have created a sample project to show the error. https://dl.dropboxusercontent.com/u/4165510/AkavacheWP8BackgroundTest.zip
Run this project and it will schedule the task and launch it for testing after a few seconds then throw the exception on the getter for BlobCache.LocalMachine

Stack Trace

{System.TypeInitializationException: The type initializer for 'Akavache.BlobCache' threw an exception. ---> System.TypeInitializationException: The type initializer for 'ReactiveUI.RxApp' threw an exception. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.UnauthorizedAccessException: Invalid cross-thread access.
   at MS.Internal.XcpImports.CheckThread()
   at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex, IntPtr constructDO)
   at System.Windows.Controls.Border..ctor()
   --- End of inner exception stack trace ---
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.Activator.CreateInstance(Type type)
   at ReactiveUI.DesignModeDetector.IsInDesignMode()
   at ReactiveUI.RxApp.InUnitTestRunner()
   at ReactiveUI.RxApp..cctor()
   --- End of inner exception stack trace ---
   at ReactiveUI.RxApp.get_suppressLogging()
   at ReactiveUI.LogHost.get_Default()
   at Akavache.BlobCache..cctor()
   --- End of inner exception stack trace ---}

Adding Akavache to a WinPhone 8 app gives "Cannot resolve dependency to assembly 'System.Runtime.InteropServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' because it has not been preloaded. When using the ReflectionOnly APIs, dep

I added Akavache 3.0.1 to my WinPhone app and get this error on the build of EVERY xaml file. I have no idea where to even start.

Adding Akavache to a WinPhone 8 app gives "Cannot resolve dependency to assembly 'System.Runtime.InteropServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event."

Static caches not initialized for WP8 (3.0.2)

Static cache properties (excluding InMemory) are not getting initialized.

Repro:

  • Start a new WP8 project (VS 2012 Update 3)
  • Add Nuget dependency to Akavache 3.0.2
  • Add App.xaml.cs code to set ApplicationName
  • Add Main.xaml.cs code to access UserAccount/Secure/LocaMachine
  • Null Ref occurs

Also note build warnings:

Warning 1 The primary reference "Akavache" could not be resolved because it has an indirect dependency on the .NET Framework assembly "System.Net.Requests, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which has a higher version "4.0.0.0" than the version "3.9.0.0" in the current target framework. AkavacheTest
Warning 2 The primary reference "Akavache" could not be resolved because it has an indirect dependency on the .NET Framework assembly "System.Net.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which has a higher version "4.0.0.0" than the version "3.9.0.0" in the current target framework. AkavacheTest

May be related to http://connect.microsoft.com/VisualStudio/feedback/details/770242

Problem deserializing dynamic objects

I'm getting an exception in my app when I try to access members of dynamic objects coming out of GetOrFetchObject, when the result is cached. I've created a slimmed down sample similar to my actual project, which demonstrates the problem.

These are the steps to reproduce:

  1. In VS 2013 Express for Windows, create a new project based on the Blank App (Windows Phone Silverlight) template, and target Windows Phone 8.0
  2. In the Package Manager Console, install-package akavache
  3. Open MainPage.xaml.cs and paste in this gist: https://gist.github.com/factormystic/3d44bf95ecb0af6684a7 don't forget to change my namespace to whatever your actual namespace is
  4. Add a button to the page, and hook up the event handler to the one that I have there, that calls RunTest() (or add your own handler and manually call RunTest(), etc)
  5. Start the app for debugging in an emulator, and click the button you added.
  6. Note in the output window, the all the debug printing from my little debug delegate comes out fine, and there are no exceptions (but possibly some additional TaskHost symbol loading messages)
  7. Click the button again. Note that this time, the exception handler message this shouldn't have happened, but did is printed

This corresponds with calling the debug print delegate on the cached result of the "ExampleDynamic" key, which is the object with the List<dynamic> in it.

This behavior is unexpected. The behavior that I want is the same behavior as when the button is first clicked, and there is no exception with the expected output.

Kinda irritating when dealing with dynamic objects from web requests, etc. What do you think?

Unable to resolve dependency 'ReactiveUI-Core (β‰₯ 5.2.0)'

I have a PCL library project (PCL 4.5 - Profile 7) and I tried to add the Akavache NuGet Package 3.20. I am getting the error "Unable to resolve dependency 'ReactiveUI-Core (β‰₯ 5.2.0)'". I am using the newly released Xamarin Studio on the Mac (version 5 build 878) with its integrated NuGet Package manager. I also tried other PCL 4.5 profiles (49, 78, 111, and 259) without any success.

Below is the output of the Package Console:

Adding akavache...
Attempting to resolve dependency 'Splat (β‰₯ 1.0.0)'.
Attempting to resolve dependency 'Newtonsoft.Json (β‰₯ 5.0.5)'.
Attempting to resolve dependency 'ReactiveUI-Core (β‰₯ 5.2.0)'.
Attempting to resolve dependency 'Rx-Main (β‰₯ 2.1.30214.0)'.
Attempting to resolve dependency 'Rx-Interfaces (β‰₯ 2.1.30214.0)'.
Attempting to resolve dependency 'Rx-Core (β‰₯ 2.1.30214.0)'.
Attempting to resolve dependency 'Rx-Linq (β‰₯ 2.1.30214.0)'.
Attempting to resolve dependency 'Rx-PlatformServices (β‰₯ 2.1.30214.0)'.
akavache Package contains PowerShell scripts which will not be run.
The Rx-Interfaces package has a license agreement which is available at http://go.microsoft.com/fwlink/?LinkID=261272
Please review this license agreement and remove the package if you do not accept the agreement.
Check the package for additional dependencies which may also have license agreements.
Using this package and any dependencies constitutes your acceptance of these license agreements.
The Rx-Core package has a license agreement which is available at http://go.microsoft.com/fwlink/?LinkID=261272
Please review this license agreement and remove the package if you do not accept the agreement.
Check the package for additional dependencies which may also have license agreements.
Using this package and any dependencies constitutes your acceptance of these license agreements.
The Rx-Linq package has a license agreement which is available at http://go.microsoft.com/fwlink/?LinkID=261272
Please review this license agreement and remove the package if you do not accept the agreement.
Check the package for additional dependencies which may also have license agreements.
Using this package and any dependencies constitutes your acceptance of these license agreements.
The Rx-PlatformServices package has a license agreement which is available at http://go.microsoft.com/fwlink/?LinkID=261272
Please review this license agreement and remove the package if you do not accept the agreement.
Check the package for additional dependencies which may also have license agreements.
Using this package and any dependencies constitutes your acceptance of these license agreements.
The Rx-Main package has a license agreement which is available at http://go.microsoft.com/fwlink/?LinkID=261272
Please review this license agreement and remove the package if you do not accept the agreement.
Check the package for additional dependencies which may also have license agreements.
Using this package and any dependencies constitutes your acceptance of these license agreements.
Installing 'Splat 1.0.0'.
Added file 'Splat.dll' to folder 'Splat.1.0.0/lib/monoandroid'.
Added file 'Splat.dll.mdb' to folder 'Splat.1.0.0/lib/monoandroid'.
Added file 'Splat.dll' to folder 'Splat.1.0.0/lib/MonoMac'.
Added file 'Splat.dll.mdb' to folder 'Splat.1.0.0/lib/MonoMac'.
Added file 'Splat.dll' to folder 'Splat.1.0.0/lib/monotouch'.
Added file 'Splat.dll.mdb' to folder 'Splat.1.0.0/lib/monotouch'.
Added file 'Splat.dll' to folder 'Splat.1.0.0/lib/Net45'.
Added file 'Splat.pdb' to folder 'Splat.1.0.0/lib/Net45'.
Added file 'Splat.dll' to folder 'Splat.1.0.0/lib/NetCore45'.
Added file 'Splat.pdb' to folder 'Splat.1.0.0/lib/NetCore45'.
Added file 'Splat.pri' to folder 'Splat.1.0.0/lib/NetCore45'.
Added file 'Splat.dll' to folder 'Splat.1.0.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'Splat.dll.mdb' to folder 'Splat.1.0.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'Splat.pdb' to folder 'Splat.1.0.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'Splat.dll' to folder 'Splat.1.0.0/lib/wp8'.
Added file 'Splat.pdb' to folder 'Splat.1.0.0/lib/wp8'.
Added file 'Splat.1.0.0.nupkg' to folder 'Splat.1.0.0'.
Successfully installed 'Splat 1.0.0'.
Installing 'Newtonsoft.Json 5.0.5'.
Added file 'Newtonsoft.Json.dll' to folder 'Newtonsoft.Json.5.0.5/lib/net20'.
Added file 'Newtonsoft.Json.xml' to folder 'Newtonsoft.Json.5.0.5/lib/net20'.
Added file 'Newtonsoft.Json.dll' to folder 'Newtonsoft.Json.5.0.5/lib/net35'.
Added file 'Newtonsoft.Json.xml' to folder 'Newtonsoft.Json.5.0.5/lib/net35'.
Added file 'Newtonsoft.Json.dll' to folder 'Newtonsoft.Json.5.0.5/lib/net40'.
Added file 'Newtonsoft.Json.xml' to folder 'Newtonsoft.Json.5.0.5/lib/net40'.
Added file 'Newtonsoft.Json.dll' to folder 'Newtonsoft.Json.5.0.5/lib/net45'.
Added file 'Newtonsoft.Json.xml' to folder 'Newtonsoft.Json.5.0.5/lib/net45'.
Added file 'Newtonsoft.Json.dll' to folder 'Newtonsoft.Json.5.0.5/lib/netcore45'.
Added file 'Newtonsoft.Json.xml' to folder 'Newtonsoft.Json.5.0.5/lib/netcore45'.
Added file 'Newtonsoft.Json.dll' to folder 'Newtonsoft.Json.5.0.5/lib/portable-net40+sl4+wp7+win8'.
Added file 'Newtonsoft.Json.xml' to folder 'Newtonsoft.Json.5.0.5/lib/portable-net40+sl4+wp7+win8'.
Added file 'Newtonsoft.Json.dll' to folder 'Newtonsoft.Json.5.0.5/lib/portable-net45+wp80+win8'.
Added file 'Newtonsoft.Json.xml' to folder 'Newtonsoft.Json.5.0.5/lib/portable-net45+wp80+win8'.
Added file 'Newtonsoft.Json.5.0.5.nupkg' to folder 'Newtonsoft.Json.5.0.5'.
Successfully installed 'Newtonsoft.Json 5.0.5'.
Installing 'Rx-Interfaces 2.1.30214.0'.
Added file 'System.Reactive.Interfaces.dll' to folder 'Rx-Interfaces.2.1.30214.0/lib/Net40'.
Added file 'System.Reactive.Interfaces.XML' to folder 'Rx-Interfaces.2.1.30214.0/lib/Net40'.
Added file 'System.Reactive.Interfaces.dll' to folder 'Rx-Interfaces.2.1.30214.0/lib/Net45'.
Added file 'System.Reactive.Interfaces.XML' to folder 'Rx-Interfaces.2.1.30214.0/lib/Net45'.
Added file 'System.Reactive.Interfaces.dll' to folder 'Rx-Interfaces.2.1.30214.0/lib/NetCore45'.
Added file 'System.Reactive.Interfaces.XML' to folder 'Rx-Interfaces.2.1.30214.0/lib/NetCore45'.
Added file 'System.Reactive.Interfaces.dll' to folder 'Rx-Interfaces.2.1.30214.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'System.Reactive.Interfaces.XML' to folder 'Rx-Interfaces.2.1.30214.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'System.Reactive.Interfaces.dll' to folder 'Rx-Interfaces.2.1.30214.0/lib/SL4-WindowsPhone71'.
Added file 'System.Reactive.Interfaces.XML' to folder 'Rx-Interfaces.2.1.30214.0/lib/SL4-WindowsPhone71'.
Added file 'System.Reactive.Interfaces.dll' to folder 'Rx-Interfaces.2.1.30214.0/lib/SL5'.
Added file 'System.Reactive.Interfaces.XML' to folder 'Rx-Interfaces.2.1.30214.0/lib/SL5'.
Added file 'System.Reactive.Interfaces.dll' to folder 'Rx-Interfaces.2.1.30214.0/lib/WP8'.
Added file 'System.Reactive.Interfaces.XML' to folder 'Rx-Interfaces.2.1.30214.0/lib/WP8'.
Added file '_._' to folder 'Rx-Interfaces.2.1.30214.0/lib/SL4'.
Added file 'Rx-Interfaces.2.1.30214.0.nupkg' to folder 'Rx-Interfaces.2.1.30214.0'.
Successfully installed 'Rx-Interfaces 2.1.30214.0'.
Installing 'Rx-Core 2.1.30214.0'.
Added file 'System.Reactive.Core.dll' to folder 'Rx-Core.2.1.30214.0/lib/Net40'.
Added file 'System.Reactive.Core.XML' to folder 'Rx-Core.2.1.30214.0/lib/Net40'.
Added file 'System.Reactive.Core.dll' to folder 'Rx-Core.2.1.30214.0/lib/Net45'.
Added file 'System.Reactive.Core.XML' to folder 'Rx-Core.2.1.30214.0/lib/Net45'.
Added file 'System.Reactive.Core.dll' to folder 'Rx-Core.2.1.30214.0/lib/NetCore45'.
Added file 'System.Reactive.Core.XML' to folder 'Rx-Core.2.1.30214.0/lib/NetCore45'.
Added file 'System.Reactive.Core.dll' to folder 'Rx-Core.2.1.30214.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'System.Reactive.Core.XML' to folder 'Rx-Core.2.1.30214.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'System.Reactive.Core.dll' to folder 'Rx-Core.2.1.30214.0/lib/SL4-WindowsPhone71'.
Added file 'System.Reactive.Core.XML' to folder 'Rx-Core.2.1.30214.0/lib/SL4-WindowsPhone71'.
Added file 'System.Reactive.Core.dll' to folder 'Rx-Core.2.1.30214.0/lib/SL5'.
Added file 'System.Reactive.Core.XML' to folder 'Rx-Core.2.1.30214.0/lib/SL5'.
Added file 'System.Reactive.Core.dll' to folder 'Rx-Core.2.1.30214.0/lib/WP8'.
Added file 'System.Reactive.Core.XML' to folder 'Rx-Core.2.1.30214.0/lib/WP8'.
Added file '_._' to folder 'Rx-Core.2.1.30214.0/lib/SL4'.
Added file 'Rx-Core.2.1.30214.0.nupkg' to folder 'Rx-Core.2.1.30214.0'.
Successfully installed 'Rx-Core 2.1.30214.0'.
Installing 'Rx-Linq 2.1.30214.0'.
Added file 'System.Reactive.Linq.dll' to folder 'Rx-Linq.2.1.30214.0/lib/Net40'.
Added file 'System.Reactive.Linq.XML' to folder 'Rx-Linq.2.1.30214.0/lib/Net40'.
Added file 'System.Reactive.Linq.dll' to folder 'Rx-Linq.2.1.30214.0/lib/Net45'.
Added file 'System.Reactive.Linq.XML' to folder 'Rx-Linq.2.1.30214.0/lib/Net45'.
Added file 'System.Reactive.Linq.dll' to folder 'Rx-Linq.2.1.30214.0/lib/NetCore45'.
Added file 'System.Reactive.Linq.XML' to folder 'Rx-Linq.2.1.30214.0/lib/NetCore45'.
Added file 'System.Reactive.Linq.dll' to folder 'Rx-Linq.2.1.30214.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'System.Reactive.Linq.XML' to folder 'Rx-Linq.2.1.30214.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'System.Reactive.Linq.dll' to folder 'Rx-Linq.2.1.30214.0/lib/SL4-WindowsPhone71'.
Added file 'System.Reactive.Linq.XML' to folder 'Rx-Linq.2.1.30214.0/lib/SL4-WindowsPhone71'.
Added file 'System.Reactive.Linq.dll' to folder 'Rx-Linq.2.1.30214.0/lib/SL5'.
Added file 'System.Reactive.Linq.XML' to folder 'Rx-Linq.2.1.30214.0/lib/SL5'.
Added file 'System.Reactive.Linq.dll' to folder 'Rx-Linq.2.1.30214.0/lib/WP8'.
Added file 'System.Reactive.Linq.XML' to folder 'Rx-Linq.2.1.30214.0/lib/WP8'.
Added file '_._' to folder 'Rx-Linq.2.1.30214.0/lib/SL4'.
Added file 'Rx-Linq.2.1.30214.0.nupkg' to folder 'Rx-Linq.2.1.30214.0'.
Successfully installed 'Rx-Linq 2.1.30214.0'.
Installing 'Rx-PlatformServices 2.1.30214.0'.
Added file 'Readme.txt' to folder 'Rx-PlatformServices.2.1.30214.0/content/Portable-Net45+WinRT45+WP8'.
Added file 'System.Reactive.PlatformServices.dll' to folder 'Rx-PlatformServices.2.1.30214.0/lib/Net40'.
Added file 'System.Reactive.PlatformServices.XML' to folder 'Rx-PlatformServices.2.1.30214.0/lib/Net40'.
Added file 'System.Reactive.PlatformServices.dll' to folder 'Rx-PlatformServices.2.1.30214.0/lib/Net45'.
Added file 'System.Reactive.PlatformServices.XML' to folder 'Rx-PlatformServices.2.1.30214.0/lib/Net45'.
Added file 'System.Reactive.PlatformServices.dll' to folder 'Rx-PlatformServices.2.1.30214.0/lib/NetCore45'.
Added file 'System.Reactive.PlatformServices.XML' to folder 'Rx-PlatformServices.2.1.30214.0/lib/NetCore45'.
Added file 'System.Reactive.PlatformServices.dll' to folder 'Rx-PlatformServices.2.1.30214.0/lib/SL4-WindowsPhone71'.
Added file 'System.Reactive.PlatformServices.XML' to folder 'Rx-PlatformServices.2.1.30214.0/lib/SL4-WindowsPhone71'.
Added file 'System.Reactive.PlatformServices.dll' to folder 'Rx-PlatformServices.2.1.30214.0/lib/SL5'.
Added file 'System.Reactive.PlatformServices.XML' to folder 'Rx-PlatformServices.2.1.30214.0/lib/SL5'.
Added file 'System.Reactive.PlatformServices.dll' to folder 'Rx-PlatformServices.2.1.30214.0/lib/WP8'.
Added file 'System.Reactive.PlatformServices.XML' to folder 'Rx-PlatformServices.2.1.30214.0/lib/WP8'.
Added file '_._' to folder 'Rx-PlatformServices.2.1.30214.0/content/Net40'.
Added file '_._' to folder 'Rx-PlatformServices.2.1.30214.0/content/Net45'.
Added file '_._' to folder 'Rx-PlatformServices.2.1.30214.0/content/NetCore45'.
Added file '_._' to folder 'Rx-PlatformServices.2.1.30214.0/content/SL4'.
Added file '_._' to folder 'Rx-PlatformServices.2.1.30214.0/content/SL4-WindowsPhone71'.
Added file '_._' to folder 'Rx-PlatformServices.2.1.30214.0/content/SL5'.
Added file '_._' to folder 'Rx-PlatformServices.2.1.30214.0/content/WP8'.
Added file '_._' to folder 'Rx-PlatformServices.2.1.30214.0/lib/Portable-Net45+WinRT45+WP8'.
Added file '_._' to folder 'Rx-PlatformServices.2.1.30214.0/lib/SL4'.
Added file 'Rx-PlatformServices.2.1.30214.0.nupkg' to folder 'Rx-PlatformServices.2.1.30214.0'.
Successfully installed 'Rx-PlatformServices 2.1.30214.0'.
Installing 'Rx-Main 2.1.30214.0'.
Added file 'Rx-Main.2.1.30214.0.nupkg' to folder 'Rx-Main.2.1.30214.0'.
Successfully installed 'Rx-Main 2.1.30214.0'.
Installing 'reactiveui-core 5.2.0'.
Added file 'ReactiveUI.dll' to folder 'reactiveui-core.5.2.0/lib/Monoandroid'.
Added file 'ReactiveUI.xml' to folder 'reactiveui-core.5.2.0/lib/Monoandroid'.
Added file 'ReactiveUI.dll' to folder 'reactiveui-core.5.2.0/lib/Monomac'.
Added file 'ReactiveUI.mdb' to folder 'reactiveui-core.5.2.0/lib/Monomac'.
Added file 'ReactiveUI.xml' to folder 'reactiveui-core.5.2.0/lib/Monomac'.
Added file 'ReactiveUI.dll' to folder 'reactiveui-core.5.2.0/lib/Monotouch'.
Added file 'ReactiveUI.xml' to folder 'reactiveui-core.5.2.0/lib/Monotouch'.
Added file 'ReactiveUI.dll' to folder 'reactiveui-core.5.2.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'ReactiveUI.xml' to folder 'reactiveui-core.5.2.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'ICSharpCode.NRefactory.CSharp.dll' to folder 'reactiveui-core.5.2.0/tools'.
Added file 'ICSharpCode.NRefactory.dll' to folder 'reactiveui-core.5.2.0/tools'.
Added file 'init.ps1' to folder 'reactiveui-core.5.2.0/tools'.
Added file 'Mono.Cecil.dll' to folder 'reactiveui-core.5.2.0/tools'.
Added file 'Nustache.Core.dll' to folder 'reactiveui-core.5.2.0/tools'.
Added file 'RxUIScaffolding.psm1' to folder 'reactiveui-core.5.2.0/tools'.
Added file 'RxUIViewModelGenerator.exe' to folder 'reactiveui-core.5.2.0/tools'.
Added file 'RxUIViewModelGenerator.exe.config' to folder 'reactiveui-core.5.2.0/tools'.
Added file 'reactiveui-core.5.2.0.nupkg' to folder 'reactiveui-core.5.2.0'.
Successfully installed 'reactiveui-core 5.2.0'.
Installing 'akavache 3.2.0'.
Added file 'Akavache.dll' to folder 'akavache.3.2.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'Akavache.pdb' to folder 'akavache.3.2.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'Akavache.xml' to folder 'akavache.3.2.0/lib/Portable-Net45+WinRT45+WP8'.
Added file 'Akavache.dll' to folder 'akavache.3.2.0/lib/net45'.
Added file 'Akavache.pdb' to folder 'akavache.3.2.0/lib/net45'.
Added file 'Akavache.xml' to folder 'akavache.3.2.0/lib/net45'.
Added file 'Akavache.dll' to folder 'akavache.3.2.0/lib/wp8'.
Added file 'Akavache.pdb' to folder 'akavache.3.2.0/lib/wp8'.
Added file 'Akavache.dll' to folder 'akavache.3.2.0/lib/WinRT45'.
Added file 'Akavache.pdb' to folder 'akavache.3.2.0/lib/WinRT45'.
Added file 'Akavache.pri' to folder 'akavache.3.2.0/lib/WinRT45'.
Added file 'Akavache.dll' to folder 'akavache.3.2.0/lib/MonoMac'.
Added file 'Akavache.dll' to folder 'akavache.3.2.0/lib/MonoAndroid'.
Added file 'Akavache.dll' to folder 'akavache.3.2.0/lib/MonoTouch'.
Added file 'akavache.3.2.0.nupkg' to folder 'akavache.3.2.0'.
Successfully installed 'akavache 3.2.0'.
Unable to resolve dependency 'ReactiveUI-Core (β‰₯ 5.2.0)'.

WinRT - missing dependencies at runtime

Running this snippet from a C# Windows Store app

// must do this first or else no soup for you
BlobCache.ApplicationName = "FlickBoard";
var store = BlobCache.UserAccount;

Gives me this sweet error:

Could not load file or assembly 'System.Reactive.WindowsRuntime, Version=2.0.20823.0, Culture=neutral, PublicKeyToken=f300afd708cefcd3' or one of its dependencies. The system cannot find the file specified.

Which isn't present when I install Akavache 2.3.0 from NuGet:

Reading the source I see these two project references:

<Reference Include="System.Reactive.Windows.Threading">
    <HintPath>..\packages\Rx-WindowStoreApps.2.0.21114\lib\WinRT45\System.Reactive.Windows.Threading.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.WindowsRuntime">
    <HintPath>..\packages\Rx-WinRT.2.0.21114\lib\WinRT45\System.Reactive.WindowsRuntime.dll</HintPath>
</Reference>

And I realise the error of my ways! So I go back to NuGet and run

Install-Package Rx-WindowStoreApps

And then it works. And then I grumble about why this assembly doesn't ship with the PlatformServices NuGet package...

NullReferenceException in Akavache

While calling the LoadImageFromUrl method I got the following stack trace with a NullReferenceException. As far as I know, we're not doing anything special here such as fiddling with the _inflightCache.

System.dll!System.Collections.Generic.LinkedList<string>.InternalInsertNodeBefore(System.Collections.Generic.LinkedListNode<string> node, System.Collections.Generic.LinkedListNode<string> newNode) + 0x23 bytes   
    System.dll!System.Collections.Generic.LinkedList<string>.AddFirst(System.Collections.Generic.LinkedListNode<string> node) + 0x23 bytes  
    ReactiveUI.dll!ReactiveUI.MemoizingMRUCache<string,System.IObservable<Akavache.Sqlite3.CacheElement>>.Get(string key, object context) + 0x1d6 bytes 
    ReactiveUI.dll!ReactiveUI.MemoizingMRUCache<string,System.IObservable<Akavache.Sqlite3.CacheElement>>.Get(string key) + 0x2d bytes  
    Akavache.Sqlite3.dll!Akavache.Sqlite3.SqlitePersistentBlobCache.GetAsync(string key) Line 88 + 0x13 bytes   C#
    Akavache.dll!Akavache.HttpMixin.DownloadUrl(Akavache.IBlobCache This, string url, System.Collections.Generic.Dictionary<string,string> headers, bool fetchAlways, System.DateTimeOffset? absoluteExpiration) Line 329 + 0x1a bytes  C#
    Akavache.dll!Akavache.BitmapImageMixin.LoadImageFromUrl(Akavache.IBlobCache This, string url, bool fetchAlways, System.DateTimeOffset? absoluteExpiration) Line 49 + 0x2d bytes C#

Cant install nuget package

I receive this error

Could not install package 'Splat 1.0.0'. You are trying to install this package into a project that targets 'portable-net45+sl50+MonoAndroid10+MonoTouch10', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

My PCL targets ios, android and .net 4.5

I have tried installing all the varieties of akavache and they all fail with this error.

Akavache.Sqlite3 on Monotouch and b0rked serializations

Hey!

Disclaimer: I didn't dig too deep on this bug, I'm trying to get feedback before spending too much time on this.

I'm trying Akavache.Sqlite3 again and I've noticed that somehow my app entered on a state where it would start and just stay on the blank black screen. After digging somewhat I found out that I had a bug on one of my view models that led to the deserialization step to fail. Now, instead of throwing an exception, it seems that Akavache.Sqlite3 was returning null, thus the AutoSuspendDelegate would just pass the null along and nothing would work.

Like I've said above, I'm not completely sure this is an Akavache.Sqlite3 bug, it may be something on my end. Does it ring any bells?

Cheers! :)

GetAndFetchLatest never calls the `fetchPredicate`

I'm trying to understand what the purpose of the fetchPredicate argument to GetAndFetchLatest is but it seems to never be called. Here is a unit test that demonstrates the ill behavior.

[Fact]
public void Test()
{
    var cache = new TestBlobCache();
    cache.InsertObject("key", "value");
    var retrieved = new List<string>();
    var prefixes = new List<DateTimeOffset>();
    cache.GetAndFetchLatest<string>("key"
    , () => {throw new InvalidOperationException();}
    , dt =>
    {
        prefixes.Add(dt);
        return false;
    }
    , DateTimeOffset.Now.AddHours(1)).Subscribe(retrieved.Add);
    cache.GetAndFetchLatest<string>("key" 
    , () => { throw new InvalidOperationException();}
    , dt =>
    {
        prefixes.Add(dt);
        return false;
    }
    , DateTimeOffset.Now.AddHours(1)).Subscribe(retrieved.Add);
    Assert.Equal(2, prefixes.Count); // This is always 0. :(
}

How do i debug a "Catastrophic failure" when using Akavache in a Windows Store App (8.1)?

i'm goofing around with a Windows Store App and when i include Akavache and try to InsertObject or GetObjectAsync, i get a COMException:

System.Runtime.InteropServices.COMException was unhandled by user code
  HResult=-2147418113
  Message=Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
  Source=mscorlib
  ErrorCode=-2147418113
  StackTrace:
       at System.StubHelpers.StubHelpers.GetWinRTFactoryObject(IntPtr pCPCMD)
       at Windows.Storage.ApplicationData.get_Current()
       at Akavache.SimpleFilesystemProvider.GetDefaultLocalMachineCacheDirectory()
       at Akavache.Registrations.<>c__DisplayClass9.<Register>b__1()
       at System.Lazy`1.CreateValue()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       at System.Lazy`1.get_Value()
       at Akavache.Registrations.<>c__DisplayClass9.<Register>b__2()
       at ReactiveUI.ModernDependencyResolver.GetService(Type serviceType, String contract)
       at ReactiveUI.DependencyResolverMixins.GetService[T](IDependencyResolver This, String contract)
       at Akavache.BlobCache.get_LocalMachine()
  InnerException: 

i'm on Windows 8.1 and making an 8.1 Store App.

i'm pretty sure that i'm just missing something because when i made a new app and included Akavache, it worked fine. Any ideas on what i could be doing wrong here? Because i think it's probably my fault, i would welcome advice on how i can debug this exception as well πŸ˜„.

i haven't included the NuGet to use SQLite3, although i plan to include it once i get my πŸ’© together.

Using Akavache with C# WPF - Help

I am trying to use Akavache in our C# wpf application. I am trying to initialize it in our AppBootstrapper, but not having much success.

        BlobCache.ApplicationName = "MobileApp";
        BlobCache.EnsureInitialized();
       dependencyResolver.RegisterLazySingleton(() => new TestBlobCache(), typeof(IBlobCache), "LocalMachine");
        dependencyResolver.RegisterLazySingleton(() => new TestBlobCache(), typeof(IBlobCache), "UserAccount");
        //dependencyResolver.Register(() => BlobCache.LocalMachine, typeof(IViewFor<IBlobCache>), "LocalMachine");
        //dependencyResolver.Register(() => BlobCache.UserAccount, typeof(IViewFor<IBlobCache>), "UserAccount");

But when I go to use BlobCache later on, both .LocalMachine and .UserAccount are null.

What am I missing?

Could not AOT the assembly Akavache.Sqlite3.dll

It looks like some of the changes in the Sqlite3 library broken Ahead Of Time compiling in Monotouch. Still trying to figure out what it was. Slowly rolling back through the checkins until I find what caused the issue.

Error MT3001: Could not AOT the assembly '/Users/nick/Development/projects/app/src/Monotouch/Project/obj/iPhone/Debug/mtouch-cache/Build/Akavache.Sqlite3.dll' (MT3001) (Project)

This checkin 2b4660f appears to be safe.

fb9ae3b - 33c0870 causes the mono compiler to crash. So without getting these to compile makes it rather hard to see if the AOT error started with them.

15195ca - this appears to be when the AOT issue started. But as I mentioned before, without being able to compile the sources above in the mono compiler I can't say this is the place for certain.

Expiration time issue

I am making a windows phone 8 app and having issue setting the expiration time.

I have something similar to below
issue is "foo" is not getting cleared from cache even after 5 seconds.

What am I doing wrong?

BlobCache.ApplicationName = "TestApp";

try
{
    var cachedValue = await BlobCache.LocalMachine.GetObjectAsync<string>("foo");
}
catch (Exception exception)
{
}

await BlobCache.LocalMachine.InsertObject("foo", "fooValue", TimeSpan.FromSeconds(5));

Unhandled Exception with SQLite - no such table CacheElement

In an app, it usually works, but every now and then when I start it, I get the following exception:

01-16 17:15:14.803 I/MonoDroid(11492): UNHANDLED EXCEPTION: SQLite.SQLiteException: no such table: CacheElement
01-16 17:15:14.803 I/MonoDroid(11492): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <IL 0x00011, 0x00068>
01-16 17:15:14.803 I/MonoDroid(11492): at System.Reactive.PlatformServices.ExceptionServicesImpl.Rethrow (System.Exception) <IL 0x00006, 0x0006b>
01-16 17:15:14.803 I/MonoDroid(11492): at System.Reactive.ExceptionHelpers.Throw (System.Exception) <IL 0x0000b, 0x00083>
01-16 17:15:14.803 I/MonoDroid(11492): at System.Reactive.Stubs.<.cctor>b__1 (System.Exception) <IL 0x00001, 0x00043>
01-16 17:15:14.803 I/MonoDroid(11492): at System.Reactive.AnonymousSafeObserver`1<System.Collections.Generic.IEnumerable`1<PB8.Models.PersonDto>>.OnError (System.Exception) <0x000b7>
01-16 17:15:14.803 I/MonoDroid(11492): at System.Reactive.ScheduledObserver`1<System.Collections.Generic.IEnumerable`1<PB8.Models.PersonDto>>.Run (object,System.Action`1<object>) <0x0018f>
01-16 17:15:14.803 I/MonoDroid(11492): at System.Reactive.Concurrency.Scheduler/<>c__DisplayClass50`1<object>.<InvokeRec1>b__4d (object) <0x000b3>
01-16 17:15:14.803 I/MonoDroid(11492): at System.Reactive.Concurrency.Scheduler.InvokeRec1<object> (System.Reactive.Concurrency.IScheduler,System.Reactive.Concurrency.Scheduler/Pair`2<object, System.Action`2<object, System.Action`1<object>>>) <0x002af>
01-16 17:15:14.803 I/MonoDroid(11492): at (wrapper delegate-invoke) System.Func`3<System.Reactive.Concurrency.IScheduler, System.Reactive.Concurrency.Scheduler/Pair`2<object, System.Action`2<object, System.Action`1<object>>>, System.IDisposable>.invoke_TResult__this___T1_T2 (System.Reactive.Concurrency.IScheduler,System.Reactive.Concurrency.Scheduler/Pair`2<object, System.Action`2<object, System.Action`1<object>>>) <IL 0x00054, 0x0013b>
01-16 17:15:14.803 I/MonoDroid(11492): at ReactiveUI.Android.AndroidUIScheduler/<Schedule>c__AnonStorey1`1<System.Reactive.Concurrency.Scheduler/Pair`2<object, System.Action`2<object, System.Action`1<object>>>>.<>m__4 () <IL 0x00013, 0x00087>
01-16 17:15:14.803 I/MonoDroid(11492): at Java.Lang.Thread/RunnableImplementor.Run () [0x0000b] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.12-series/c789d807/source/monodroid/src/Mono.Android/src/Java.Lang/Thread.cs:36
01-16 17:15:14.803 I/MonoDroid(11492): at Java.Lang.IRunnableInvoker.n_Run (intptr,intptr) [0x00009] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.12-series/c789d807/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Java.Lang.IRunnable.cs:71
01-16 17:15:14.803 I/MonoDroid(11492): at (wrapper dynamic-method) object.3d7a414c-5b58-4343-ba4c-a0f855415db1 (intptr,intptr) <IL 0x00011, 0x0003b>
Unhandled Exception:

SQLite.SQLiteException: no such table: CacheElement

01-16 17:15:20.739 E/mono    (11492): 
01-16 17:15:20.739 E/mono    (11492): Unhandled Exception:
01-16 17:15:20.739 E/mono    (11492): SQLite.SQLiteException: no such table: CacheElement
01-16 17:15:20.739 E/mono    (11492):   at SQLite.SQLite3.Prepare2 (IntPtr db, System.String query) [0x0001b] in /Users/oren/git/Akavache/Akavache.Sqlite3/SQLite.cs:2351 
01-16 17:15:20.739 E/mono    (11492):   at SQLite.SQLiteCommand.Prepare () [0x00000] in /Users/oren/git/Akavache/Akavache.Sqlite3/SQLite.cs:1659 
01-16 17:15:20.739 E/mono    (11492):   at SQLite.SQLiteCommand+<ExecuteDeferredQuery>c__Iterator0`1[Akavache.Sqlite3.CacheElement].MoveNext () [0x00038] in /Users/oren/git/Akavache/Akavache.Sqlite3/SQLite.cs:1585 
01-16 17:15:20.739 E/mono    (11492):   at System.Collections.Generic.List`1[Akavache.Sqlite3.CacheElement].AddEnumerable (IEnumerable`1 enumerable) [0x00000] in <filename unknown>:0 
01-16 17:15:20.739 E/mono    (11492):   at System.Collections.Generic.List`1[Akavache.Sqlite3.CacheElement]..ctor (IEnumerable`1 collection) [0x00000] in <filename unknown>:0 
01-16 17:15:20.739 E/mono    (11492):   at System.Linq.Enumerable.ToList[CacheElement] (IEnumerable`1 source) [0x00000] in <filename unknown>:0 
01-16 17:15:20.739 E/mono    (11492):   at SQLite.SQLiteCommand.ExecuteQuery[CacheElement] () [0x00000] in /Users/oren/git/Akavache/Akavache.Sqlite3/SQLite.cs:1554 
01-16 17:15:20.739 E/mono    (11492):   at SQLite.S
01-16 17:15:20.739 E/mono-rt (11492): [ERROR] FATAL UNHANDLED EXCEPTION: SQLite.SQLiteException: no such table: CacheElement
01-16 17:15:20.739 E/mono-rt (11492):   at SQLite.SQLite3.Prepare2 (IntPtr db, System.String query) [0x0001b] in /Users/oren/git/Akavache/Akavache.Sqlite3/SQLite.cs:2351 
01-16 17:15:20.739 E/mono-rt (11492):   at SQLite.SQLiteCommand.Prepare () [0x00000] in /Users/oren/git/Akavache/Akavache.Sqlite3/SQLite.cs:1659 
01-16 17:15:20.739 E/mono-rt (11492):   at SQLite.SQLiteCommand+<ExecuteDeferredQuery>c__Iterator0`1[Akavache.Sqlite3.CacheElement].MoveNext () [0x00038] in /Users/oren/git/Akavache/Akavache.Sqlite3/SQLite.cs:1585 
01-16 17:15:20.739 E/mono-rt (11492):   at System.Collections.Generic.List`1[Akavache.Sqlite3.CacheElement].AddEnumerable (IEnumerable`1 enumerable) [0x00000] in <filename unknown>:0 
01-16 17:15:20.739 E/mono-rt (11492):   at System.Collections.Generic.List`1[Akavache.Sqlite3.CacheElement]..ctor (IEnumerable`1 collection) [0x00000] in <filename unknown>:0 
01-16 17:15:20.739 E/mono-rt (11492):   at System.Linq.Enumerable.ToList[CacheElement] (IEnumerable`1 source) [0x00000] in <filename unknown>:0 
01-16 17:15:20.739 E/mono-rt (11492):   at SQLite.SQLiteCommand.ExecuteQuery[CacheElement] () [0x00000] in /Users/oren/git/Akavache/Akavache.Sqlite3/SQLite.cs:1554 
The program 'Mono' has exited with code 0 (0x0).

IO Error accessing file in cache

Hey,

I keep getting IOErrors from Akavache where it says the file is being accessed by another process. I am wondering if it is a threading issue with my code, is this something you have seen before? Should Akavache be dealing with these exceptions and retrying if it happens? On a separate note, with the new version you seem to have changed from SecretCache to BlobCache if the storage is in roaming. The pr suggests that you can override this to put it back to SecretCache but I have been unable to find how, is it possible?

Thanks in advance

Adam

[WinRT] GetOrFetchObject always returns null when using roaming/local storage

While the examples in the README work nicely, I wanted to use the more elegant APIs like this:

var result = await blobCache.GetOrFetchObject(
             "KeyOne",
             () => Observable.Return(new SomethingUseful { Id = 1 }));

Assert.AreEqual(1, existingValueNoExpiration.Id);

Where SomethingUseful is just a POCO:

class SomethingUseful { public int Id; }

Expected: when GetOrfFetchObject does not find the object in cache, it should call fetch function and return result of fetch.
Actual: never calls fetch, always returns null.

Failing unit tests: https://gist.github.com/4465472

Problem with Akavache and Punchlock in WinRT

I'm running into an issue when using Punchlock with Akavache.

I'm using the line

return await _opQueue.Enqueue(1, async () => await BlobCache.LocalMachine.LoadImageFromUrl(imageUrl));

to queue up image loading from an external resource. This works fine the first time it goes off to get the images. However, when it has already persisted the images, it never seems to return.

Thanks!

API Sketches for Transactions

API Sketches for My Sweetheart the Drunk Transaction

  • The mindblowing idea is, you simply cannot access normal read/write operations outside of a transaction. They're not even on the IBlobCache object. Instead, you create a transaction and the returned transaction object has all of the methods you're used to. You can't Hold It Wrongβ„’.

Old:

await BlobCache.LocalMachine.InsertObject("Foo", bar);
await BlobCache.LocalMachine.GetObjectAsync<Baz>("Bamf");

Perhaps New:

// Return value must:
// * Return the value of the transaction at the end or be Unit
// * Have a Cancel() method to cancel the transaction
await BlobCache.LocalMachine.InTransaction(cache => async {
    await cache.InsertObject("Foo", Bar);
    return await cache.GetObjectAsync<Baz>("Bamf");
});

or perhaps just:

await BlobCache.LocalMachine.InSyncTransaction(cache => {
    // These all run in order
    cache.InsertObject("Foo", Bar);
    cache.InsertObject("Baz", Bamf);

    return cache.GetObject<Bard>("Shakespeare");
});

Maybe both? There should also be a method for one-offs:

// I hate the name "SingleOp", find something better
await BlobCache.LocalMachine.SingleOp().GetAllObjects<Bamf>();

or times when you can't jam everything into a single Lambda function:

var transaction = BlobCache.LocalMachine.BeginTransaction();

await transaction.GetObjectAsync<Bar>("Foo");

transaction.Dispose();   // Finishes the transaction
//or
transaction.Cancel();    // Aborts the transaction.

Open Questions

  • Are operations inside a transaction guaranteed to run sequentially? Should they be?
  • Do transactions only apply to writes, or does it guarantee a consistent read "view of the world".

SQLite.SQLiteException

Message: "Locked"
Stacktrace:

   at SQLite.PreparedSqlLiteInsertCommand.ExecuteNonQuery(Object[] source) in z:\github\Akavache\Akavache.Sqlite3\SQLite.cs:line 1847
   at SQLite.SQLiteConnection.Insert(Object obj, String extra, Type objType) in z:\github\Akavache\Akavache.Sqlite3\SQLite.cs:line 949
   at SQLite.SQLiteAsyncConnection.<>c__DisplayClass8.<InsertAsync>b__7(SQLiteConnection conn) in z:\github\Akavache\Akavache.Sqlite3\SQLiteAsync.cs:line 138
   at SQLite.SQLiteConnectionPool.<>c__DisplayClass1`1.<EnqueueConnectionOp>b__0() in z:\github\Akavache\Akavache.Sqlite3\SQLiteAsync.cs:line 278
   at Akavache.KeyedOperationQueue.<>c__DisplayClass15`1.<SafeStart>b__14() in z:\github\Akavache\Akavache\Portable\KeyedOperationQueue.cs:line 146

Version I'm using: 3.2.0
I get this exception when doing some inserts into the BlobCache.
I haven't yet had the time to create a simple reproduction, but I'll try to come up with one soon.

Akavache.Sqlite3 3.1.1 does not pass peverify

Here are the results of running peverify on the released binaries:

***** Mono/Akavache.Sqlite3.dll
Could not load class with token 2000002
* Assertion at class.c:5594, condition `!mono_loader_get_last_error ()' not met

Abort trap: 6

***** Monoandroid/Akavache.Sqlite3.dll
Missing method .ctor in assembly /Users/loyful/Downloads/Akavache.3.1.1 (1)/Monoandroid/Akavache.Sqlite3.dll, type System.Runtime.CompilerServices.AsyncStateMachineAttribute
Error: Invalid CustomAttribute content row 268 Value field 0x00000f4a
Error: CustomAttribute: Invalid constructor
Error count: 2

***** Monotouch/Akavache.Sqlite3.dll
Missing method .ctor in assembly /Users/loyful/Downloads/Akavache.3.1.1 (1)/Monotouch/Akavache.Sqlite3.dll, type System.Runtime.CompilerServices.AsyncStateMachineAttribute
Error: Invalid CustomAttribute content row 268 Value field 0x00000f4a
Error: CustomAttribute: Invalid constructor
Error count: 2

***** Net45/Akavache.Sqlite3.dll
Could not load class with token 2000002
* Assertion at class.c:5594, condition `!mono_loader_get_last_error ()' not met

Abort trap: 6

***** WinRT45/Akavache.Sqlite3.dll
Error: AssemblyRef table row 16 has invalid Flags 00000200
Error count: 1

AFAIU, those with Abort trap: 6 are actually passing peverify since even Xamarin.Mobile.dll triggers this behavior. Monoandroid and Monotouch, however, seem to have some genuine errors.

On a private Xamarin bug, Zoltan Varga stated that there were some bugs on mcs that caused some miscompilations, but that those bugs have since been fixed.

What Xamarin.iOS version was used to compile these binaries? (Version 7.0.2, current stable, creates binaries with the same problems.)

If you use your current setup, do your final binaries still not pass peverify? If so, then I guess it's time to fill a public mcs bug report.

Add Splat NuGet dependency

I tried calling the DownloadUrl extension method to IBlobCache but it returns a Splat.IBitmap. What is even a splat?

I think you just need to add a package dependency to Splat.

WinRT LoadImageFromUrl issue

In WinRT I haven't been successful using LoadImageFromUrl.

  MainImage.ImageSource = (await BlobCache.LocalMachine.LoadImageFromUrl(imageMetaData.imageUrl)).ToNative();
The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

   at Windows.UI.Xaml.Media.Imaging.WriteableBitmap..ctor(Int32 pixelWidth, Int32 pixelHeight)
   at Splat.PlatformBitmapLoader.<Load>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Reactive.PlatformServices.ExceptionServicesImpl.Rethrow(Exception exception)
   at System.Reactive.ExceptionHelpers.ThrowIfNotNull(Exception exception)
   at System.Reactive.Subjects.AsyncSubject`1.GetResult()
   at ThePaperWall.WinRT.HubPage.<OnNavigatedTo>d__4.MoveNext() in c:\Users\jimmy_000\Documents\GitHub\ThePaperWallApps\src\ThePaperWall.WinRT\HubPage.xaml.cs:line 130

Fx Version in Cache Key

I checked out the cache key created by LoginMixin.

"System.Tuple`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, 
PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, 
Culture=neutral,PublicKeyToken=b77a5c561934e089]]

What happens when we upgrade to .NET 4.5? Or eventually 5.0? Will our caches all be invalid all of a sudden?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.