[Kde-pim] Akonadi resources and collection IDs

Dmitry Ivanov vonami at gmail.com
Thu Jun 19 10:32:15 BST 2008


On 6/17/08, Dmitry Ivanov <vonami at gmail.com> wrote:
> Hi there,
>
>  While trying to add a D-Bus interface to the RSS resource I ran into a
>  problem I'd like to discuss.
>
>  The D-Bus interface has a method to synchronize a feed:
>
>  synchronizeFeed( XmlUrl ) // actually this might another id
>
>  To trigger the collection synchronization the resource should call
>
>  synchronizeCollection( quint64 id ) // id is Akonadi::Collection::Id
>
>  The problem is, given how the resource is implemented now, it doesn't
>  store IDs for collections. Then the user launches resource configuration
>  dialog, he can import existing feeds from an OPML file. The resource loads
>  the feeds, converts them to collections, and then calls
>  ResourceBase::synchronize(). The current collection tree eventually
>  reaches Akonadi::CollectionSync which commits the collections to the
>  database. This way the resource ends up with collections without valid IDs.
>
>  And I bet I'll have to have collection IDs while implementing other
>  operations in the future.
>
>  The proposed solution is as follows:
>
>  1. The resource doesn't rely on Akonadi::CollectionSync anymore, it
>  creates and commits collections itself, receiving IDs from
>  Akonadi::CollectionCreateJob.
>
>  2. The clients shouldn't add new feeds via Akonadi::CollectionCreateJob,
>  instead they use the D-Bus interface. The resource receives XmlUrl,
>  creates a new collection, and commits it.
>
>  Why add new feeds via the D-Bus interface? Why shouldn't clients create
>  collections themselves and commit them to Akonadi (via a standard
>  action)? Because of remoteId. I believe only the resource should assign
>  remoteId to a newly added feed/collection. remoteId may point to
>  something in a storage of feeds/items if the resource have such a storage
>  (like metakit in Akregator), or may point to a feed in online feed reader in
>  case of a dedicated RSS resource for this online feed reader.
>
>  Although a client can create/commit a collection on its own, then the
>  resource gets a notification via collectionAdded() and assigns a proper
>  remoteId. Sounds a bit "kludgy".
>
>  3. Upon (re)start, the resource reloads the collection tree from Akonadi.
>
>  Any better approaches? Do you foresee any problems with the proposed
>  solution?
>

The solution described above works fine (the code is in svn). Another
approach would be to retrieve the collection ID on demand (i.e. when
synchronizeCollection() is called ) via CollectionFetchJob and save it
inside the resource to reuse later. To push changes in collections I can
use collectionsRetrievedIncremental(). But it turned out that
Akonadi::CollectionSync loses changes made to collections (I tested with
collection's name).

I've worked up a testcase to show the bug. Steps to reproduce:

1. Start akonadiconsole and add a new RSS resource, then import
the attached OPML file (some values are hardcoded to make it easier
to trigger the bug). The resource will import the feeds and sync them.
Check the collection names in akonadiconsole's browser. The name
of the test collection is "OLD NAME" (remoteId="bug").

2. Fire up qdbusviewer, select org.kde.krss and call triggerBug().
This forces the resource to change the name of the test collection
(remoteId="bug") to "NEW NAME" and pass the changed collection
to collectionsRetrievedIncremental() ( via a call to
synchronizeCollectionTree() ).

3. Check the test collection in akonadiconsole's browser: the name
remains the same.

The whole code for krss is in the attached tarball (svn repo contains
totally different code). I've removed a lot of code not relevant to
the testcase.

I had a look at Akonadi::CollectionSync. Actually it doesn't commit
the changed collections:

void CollectionSync::slotLocalListDone(KJob * job)
{

 .....


  // added / updated
  foreach ( const Collection &c, d->remoteCollections ) {
    if ( c.remoteId().isEmpty() ) {
      kWarning( 5250 ) << "Collection '" << c.name() <<"' does not
have a remote identifier - skipping";
      continue;
    }

    ^^^
    'c' is the test collection got from collectionsRetrievedIncremental()


    Collection local = d->localCollections.value( c.remoteId() );
    d->unprocessedLocalCollections.remove( local );

   ^^^
   'local' is the collection fetched from the database by CollectionSync


    // missing locally
    if ( !local.isValid() ) {
      // determine local parent
      Collection localParent;
      if ( c.parent() >= 0 )
        localParent = Collection( c.parent() );
      if ( c.parentRemoteId().isEmpty() )
        localParent = Collection::root();
      else
        localParent = d->localCollections.value( c.parentRemoteId() );

      // no local parent found, create later
      if ( !localParent.isValid() ) {
        d->orphanRemoteCollections << c;
        continue;
      }

      createLocalCollection( c, localParent );
      continue;
    }

    // update local collection
    d->pendingJobs++;
    CollectionModifyJob *mod = new CollectionModifyJob( local, this );
    connect( mod, SIGNAL(result(KJob*)), SLOT(slotLocalChangeDone(KJob*)) );

   ^^^
   CollectionSync commits the collection it just fetched from the database.
   Shouldn't it commit collection 'c'?


The above logic does look like a bug to me.

Dmitry

-- 
A: Because it destroys the flow of the conversation
Q: Why is top-posting bad?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: krss.tar
Type: application/x-tar
Size: 163840 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-pim/attachments/20080619/c2797e9a/attachment.tar>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: feeds.opml
Type: application/octet-stream
Size: 832 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-pim/attachments/20080619/c2797e9a/attachment.obj>
-------------- next part --------------
_______________________________________________
KDE PIM mailing list kde-pim at kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
KDE PIM home page at http://pim.kde.org/


More information about the kde-pim mailing list