Archomeda/Gw2Sharp

Archive caching results in empty ZIP files

Opened this issue · 4 comments

It seems that for regular API requests the archive caching isn't working.
It has been reported that the resulting ZIP was empty.

While I personally cannot recommend using a file based caching for JSON API requests, some investigation is warranted to see what is going on because the interface does suggest that it's possible.

This probably needs some fixing when the problem is found.

Ref: https://discordapp.com/channels/384735285197537290/589031897963692034/669911617722515466

@werdes Do you still have problems with this? Otherwise I'll close it sometime next week.

Haven‘t tried so far, but feel free to close. If i come along this again i‘ll let you know and link this issue.

Sounds good! 😄

This issue seems to have popped up again, and it doesn't only apply for regular API requests, but also render requests.

Reproducible steps:

using Gw2Sharp;
using Gw2Sharp.WebApi.Caching;

Console.WriteLine("Hello, World!");

var connection = new Connection
{
    CacheMethod = new ArchiveCacheMethod("cache.zip"),
    RenderCacheMethod = new ArchiveCacheMethod("render-cache.zip")
};

using var client = new Gw2Client(connection);

var items = await client.WebApi.V2.Items.PageAsync(0).ConfigureAwait(false);
var itemUrl = items[0].Icon.Url;
var icon = await client.WebApi.Render.DownloadToByteArrayAsync(itemUrl).ConfigureAwait(false);

Console.WriteLine(items.Count);
Console.WriteLine(icon.Length);

I traced it to an unlucky construction of IDisposable chains.
Every ICacheMethod is IDisposable, which means that you should dispose it after you're done with it. Sadly Gw2Sharp doesn't seem to dispose this object automatically.
The core of the issue is that because of this, the ZipArchive that's used under the hood isn't disposed, meaning that changes are not written to disk.

The current workaround is to keep track of the ArchiveCacheMethod instance outside the Connection object, and dispose of it manually when the Gw2Client and Connection objects are no longer needed.