Caching and Storage

xbmcswift2 offers a few options for caching and storage to help improve the user experience of your addon. swift offers a simple storage mechanism that allows you to store arbitraty python objects to use between requests.

Warning

The current implementation of xbmcswift2’s storage is very basic and is not thread safe. If your addon does background calls via the context menu and manipulates storages in these backgound threads, you might run into some issues.

Storing Arbitraty Python Objects

All caches/storage objects in xbmcswift2 act like python dictionaries. So to get a cache, simply call the get_storage method.

people = plugin.get_storage('people')

# now we can use people like a regular dict
people['jon'] = 'developer'
people.update({'dave': 'accountant'})

people.items()
# [('jon', 'deveoper'), ('dave', 'accountant')]

Caches are automatically persisted to disk each time an addon finishes execution. If you would like to sync the cache to disk manually, you can call cache.sync() directly. However, this is not normally necessary.

File Formats

By default, caches are saved to disk in the pickle format. This is convenient since it can store Python objects. However, you can also pass ‘csv’ or ‘json’ for the file_format keyword arg to the get_storage call.

Expirations

Caches also offer an optional argument, TTL, which is the max lifetime for objects specified in minutes.

people = plugin.get_storage('people', TTL=24)

Caching Decorator

xbmcswift2 provides a convenient caching decorator to automatically cache the output of a function. For example, suppose we have a function get_api_data, that goes out to a remote API and fetches lots of data. If the website only updates the API once a day, it doesn’t make sense to make this request every time the addon is run. So we can use the caching decorator with a TTL argument.

@plugin.cached(TTL=60*24)
def get_api_data();
    # make remote request
    data = get_remote_data()
    return data

The default TTL is 1 day if not provided.

Caching Views

It’s also possible to cache views (functions decorated with plugin.route()). To simplify addon code, there is a special decorator called cached_route. All of the arguments to cached_route are the same as the regular route decorator. Currently, it is not possible to specify a TTL for this decorator; it defaults to 24 hours.

@plugin.cached_route('/')
def main_menu();
    # do stuff

Warning

This is only currently possible for views that return lists of dictionaries. If you call plugin.finish() you cannot currently cache the view. See the below section ‘Caveats’ for more information.

Warning

It is currently only possible to attach a single cached_route to a view. If you have multiple routes on a given view, try refactoring some logic out to a new function that can be cached, instead of using the cached_route decorator.

Caveats

The caching features of xbmcswift2 are still young and thus have some potential problems to be aware of.

  • First, if you are calling plugin.finish from a view, it is not currently possible to cache the view. This is because there are a few side effects which happen in finish which would not be cached. If this is the case, perhaps you can move some functionality in your view into a new function, and cache that result instead.
  • Ensure variables are part of your method signature. If you cache a given function, ensure that all possible inputs are in your method signature. xbmcswift2 uses the arguments passed to your function as the unique key for the cache. Therefore it’s possible to cache different return values for different inputs for a function. But if you check some global state from inside your function, the caching logic will have no knowlege of this and will return the wrong result.
  • Currently, caches can grow very large since they do not automatically purge themselves based on filesize. Depending on what you are caching, you might need to introduce some logic to clear the cache.
cache = plugin.get_cache('people')
cache.clear()
cache.sync()
  • It’s advisable to include caching as the final step in your development process. If you are still developing your addon, occasionally incorrect return values can be cached which will cause you headaches.

Table Of Contents

Related Topics

This Page