New API

This page was destined to gather all thoughts, ideas and drafts for the new Accomplishments API that were meant to be implemented for 0.2 milestone.

It was considered as notes https://blueprints.launchpad.net/ubuntu-accomplishments-daemon/+spec/new-accomplishments-api

The following draft has already been implemented as a part of work for 0.2 release!

Specification draft

Logic changes

Accomplishment ID's

All functions (both internal and external) should never use (application, accom) as path. They should be rewritten to use accomplishment ID as parameter.

Storing all accomplishments data in memory

Currently whenever an accomplishment data is used, it is reloaded from the file(s), and read by ConfigParser. This is not very efficient, and may be even less when we'll use more basic functions for cleaner code.

Preserving .trophies

It was recently decided to never erase user's accomplishments, because some of them may be not achievable again. That means that the daemon should never delete accomplishments - it the signature is incorrect it should delete the .asc file, but never the trophy (if .asc is missing then it will not be treated as accomplished anyway).

New collection structure

It is planned to use two-leveled accomplishment hierarchy. A collection will contain several (or one) set(s), and API code needs to be adjusted for this, as currently no subdirectories are allowed within a collection.

Functions and code restructuring

Access functions

For easy access to accomplishments data there should be simple wrappers provided.

get_accomplishment_data(accomID) would return a dictionary of all data for given accomplishment ID (of course it should also take care about using appropriate locale).

Similarly, get_trophy_data(accomID) would return such dictionary for a .trophy file (if it exists).

Another helpful functions would be get_accomplishment_script_path(accomID).

Unifying code

There are many things that are done in the source code several times in different places.

For example, displaying a bubble "You have accomplished X" is written several times. There should be a single function display_accomplished_bubble(accomID) that would do this.

Another issue is that some basic operations are performed on the viewer's side. For example, checking if an accomplishment has a valid .trophy - there should be a simple API function get_accomplishment_is_completed(accomID) which would check if there is a .trophy file, whether .asc is also needed etc., and return just True/False, because that's what clients will need. Such function would be also helpful internally, e.g. when checking if dependencies are met.

"get all data" functions

To maintain simplicity of code, we should get rid of functions that are meant to provide all data that is available. A good example is get_all_accomplishments_and_status(). The problem is not that it is not efficient at all (though it indeed is) and it may take lots of time to complete. The problem is that only 1% of the data it provides is actually required by the caller (it returns an array of dictionaries of all fields of all available .accomplishments). It would much better if there were three separate functions for that: get_accomplishments_list() which would return a list of all accomplishment IDs available, and get_accomplishment_data(accomID) which would provide all data from .accomplishment file, and get_accomplishment_is_completed(accomID) which would determine if the accomplishment has been achieved.

This way it is 1) easier to maintain functionality 2) more efficient 3) easier for clients to get the data they actually need.

Listing accomplishments from collection or set

For listing accomplishments, it might be useful if there was present a function like list_all_accomplishments_in_set(setID), which - for given setID (e.g. ubuntu-community/launchpad) would return a list (array) of accomplishment IDs, of all accoms that belong to this set. Similarly for collections. Also, provided that we keep all accomplishments data in memory, it might be also easy to get a list of accomplishments from one category - clients might potentially take great advantage of such functions. Another use is listing all accomplishments that depend on a given one (see Scripts queue paragraph).

Unifying function names

It may be a good idea to keep function names unified - especially these, that are meant to be used by external applications. While prefix get_ which is already used is easy to define, we might consider using get_accomplishment_ or get_accom_ for functions that return accomplishment's parameters (like is_valid, data, depends). Functions that are supposed to return a list of accomplishment IDs (like all accoms from a set, or a category, or all unlocked opportunities etc.) get_accomplishments_, get_accoms_, list_accomplishments_ or list_accoms_.

Scriptrunner

Scripts queue

As suggested by Twistd/Python experts, it is a very good idea to put all scripts that need to be run in a queue, using a producer-consumer threads model. The scriptrunner takes scripts that need running from the front of the queue, and when a script is scheduled to be run, it is added to the end of the queue (unless it already is in the queue).

This technique ensures much greater efficiency, because this way we can easily schedule only a few scripts that need to be run, instead of re-running all, as it takes place in current implementation. This would significantly shorten the time needed to check all accomplishments, including unlocked dependencies (when accomplishments get unlocked, instead of running all scripts we might just check the newly unlocked accoms [listing function list_accomplishments_depending_on(accomID)]). Moreover, this way we can avoid unnecessary running scripts, and thus save resources. Also, this would make it possible to re-check one particular accomplishment. Functions named like run_script(accomID) and run_scripts_all() would take care of scheduling the script at the end of the queue - and wake up the scriptrunner thread using a mutex / conditional variable.

Functions

This is a suggested list of functions and their behavior that should be available in the new API. As this is a proposed list, it may be changed as the discussion is still in progress.

Access functions

Listing functions

More listing functions may be implemented on demand.

Scriptrunner functions

Misc functions

Accomplishments/NewAPI (last edited 2012-05-17 20:16:55 by rafalcieslak256)