Skip to content

{ Monthly Archives } September 2014

SyncEvolution 1.4.99.4 released

This is the first release candidate for 1.5. No further changes are planned except for fixing yet-to-be-discovered bugs – so find them now! :-)

SyncEvolution 1.4.99.4 released

This is the first release candidate for 1.5. No further changes are planned except for fixing yet-to-be-discovered bugs – so find them now! :-)

One focus in this release was on minimizing CPU consumption and disk
writes. The most common case, a two-way sync with no changes on either
side, no longer rewrites any meta data files. CPU consumption during
local sync was reduced to one third by exchanging messages via shared
memory instead of internal D-Bus. Redundant vCard decode/encode on the
sending side of PBAP and too agressive flushing of meta data during a
normal sync were removed. Altogether, sending 1000 contacts with photo
data in a refresh-from-server local sync takes only one sixth of the
CPU cycles compared to 1.3.99.3 (measured with valgrind’s callgrind on
x86_64).

Based on community feedback and discussions, the terminology used in
SyncEvolution for configuration, local sync and database access was
revised. Some usability issues with setting up access to databases
were addressed. For Google, the obsolete SyncML config template was
removed and CalDAV/CardDAV were merged into a single “Google”
template.

Using Google Calendar/Contacts with OAuth2 authentication on a
headless server becomes a bit easier: it is possible to set up access
on one system with a GUI using either gSSO or GNOME Online Accounts,
then take the OAuth2 refresh token and use it in SyncEvolution on a
different system. See the new OAuth2 backend README.

Some issues accessing Apple iCloud were fixed such that CardDAV works
by just giving SyncEvolution username=foobar@icloud.com and password. No
throrough testing was done, so iCloud support is still experimental.

The PIM Manager API also supports Google Contact syncing. Some
problems with suspending a PBAP sync were fixed. Suspend/abort can
be tested with the sync.py example.

The EDS memo backend is able to switch between syncing in plain
text and iCalendar 2.0 VJOURNAL automatically.

Details:

  • oauth2: new backend using libsoup/libcurl

    New backend implements identity provider for obtaining OAuth2 access
    token for systems without HMI support.
    Access token is obtained by making direct HTTP request to OAuth2 server
    and using refresh token obtained by user in some other way.
    New provider automatically updates stored refresh token when OAuth2
    server is issuing new one.

  • PBAP: use raw text items

    This avoids the redundant parse/generate step on the sending
    side of the PBAP sync.

  • datatypes: raw text items with minimal conversion (FDO #52791)

    When using “raw/text/calendar” or “raw/text/vcard” as SyncEvolution
    “databaseFormat”, all parsing and conversion is skipped. The backend’s
    data is identical to the item data in the engine. Finding duplicates
    in a slow sync is very limited when using these types because the entire
    item data must match exactly.

    This is useful for the file backend when the goal is to store an exact copy
    of what a peer has or for limited, read-only backends (PBAP). The downside
    of using the raw types is that the peer is not given accurate information
    about which vCard or iCalendar properties are supported, which may cause
    some peers to not send all data.

  • engine: flush map items less frequently

    The Synthesis API does not say explicitly, but in practice all map
    items get updated in a tight loop. Rewriting the m_mappingNode (case
    insensitive string comparisons) and serialization to disk
    (std::ostrstream) consume a significant amount of CPU cycles and cause
    extra disk writes that can be avoided by making some assumptions about
    the sequence of API calls and flushing only once.

  • SoupTransport: drop CA file check

    It used to be necessary to specify a CA file for libsoup to enable SSL
    certificate checking. Nowadays libsoup uses the default CA store
    unless told otherwise, so the check in SyncEvolution became
    obsolete. However, now there is a certain risk that no SSL checking is
    done although the user asked for it (when libsoup is not recent enough
    or compiled correctly).

  • local sync: exchange SyncML messages via shared memory

    Encoding/decoding of the uint8_t array in D-Bus took a surprisingly
    large amount of CPU cycles relative to the rest of the SyncML message
    processing. Now the actual data resides in memory-mapped temporary
    files and the D-Bus messages only contain offset and size inside these
    files. Both sides use memory mapping to read and write directly.

    For caching 1000 contacts with photos on a fast laptop, total sync
    time roughly drops from 6s to 3s.

    To eliminate memory copies, memory handling in libsynthesis or rather,
    libsmltk is tweaked such that it allocates the buffer used for SyncML
    message data in the shared memory buffer directly. This relies on
    knowledge of libsmltk internals, but those shouldn’t change and if they
    do, SyncEvolution will notice (”unexpected send buffer”).

  • local sync: avoid updating meta data when nothing changed

    The sync meta data (sync anchors, client change log) get updated after
    a sync even if nothing changed and the existing meta data could be
    used again. This can be skipped for local sync, because then
    SyncEvolution can ensure that both sides skip updating the meta
    data. With a remote SyncML server that is not possible and thus
    SyncEvolution has to update its data.

    This optimization is only used for local syncs with one source. It is
    based on the observation that when the server side calls
    SaveAdminData, the client has sent its last message and the sync is
    complete. At that point, SyncEvolution can check whether anything has
    changed and if not, skip saving the server’s admin data and stop the
    sync without sending the real reply to the client.

    Instead the client gets an empty message with “quitsync” as content
    type. Then it takes shortcuts to close down without finalizing the
    sync engine, because that would trigger writing of meta data
    changes. The server continues its shutdown normally.

    This optimization is limited to syncs with a single source, because
    the assumption about when aborting is possible is harder to verify
    when multiple sources are involved.

  • PIM: include CardDAV in CreatePeer()

    This adds “protocol: CardDAV” as a valid value, with corresponding
    changes to the interpretation of some existing properties and some new
    ones. The API itself is not changed.

    Suspending a CardDAV sync is possible. This freezes the internal
    SyncML message exchange, so data exchange with the CardDAV server may
    continue for a while after SuspendPeer().

    Photo data is always downloaded immediately. The “pbap-sync” flag
    in SyncPeerWithFlags() has no effect.

    Syncing can be configured to be one-way (local side is read-only
    cache) or two-way (local side is read/write). Meta data must be
    written either way, to speed up caching or allow two-way syncing. The
    most common case (no changes on either side) will have to be optimized
    such that existing meta data is not touched and thus no disk writes
    occur.

  • PIM: handle SuspendPeer() before and after transfer (FDO #82863)

    A SuspendPeer() only succeeded while the underlying Bluetooth transfer
    was active. Outside of that, Bluez errors caused SyncEvolution to
    attempt a cancelation of the transfer and stopped the sync.

    When the transfer was still queueing, obexd returns
    org.bluez.obex.Error.NotInProgress. This is difficult to handle for
    SyncEvolution: it cannot prevent the transfer from starting and has to
    let it become active before it can suspend the transfer. Canceling
    would lead to difficult to handle error cases (like partially parsed
    data) and therefore is not done.

    The Bluez team was asked to implement suspending of queued transfers
    (see “org.bluez.obex.Transfer1 Suspend/Resume in queued state” on
    linux-bluetooth@vger.kernel.org), so this case might not happen
    anymore with future Bluez.

    When the transfer completes before obexd processes the Suspend(),
    org.freedesktop.DBus.Error.UnknownObject gets returned by
    obexd. SyncEvolution can ignore errors which occur after the active
    transfer completed. In addition, it should prevent starting the next
    one. This may be relevant for transfer in chunks, although the sync
    engine will also stop asking for data and thus typically no new
    transfer gets triggered anyway.

  • PIM: add suspend/resume/abort to sync.py

    CTRL-C while waiting for the end of a sync causes an interactive
    prompt to appear where one can choose been suspend/resume/abort and
    continuing to wait. CTRL-C again in the prompt aborts the script.

  • PIM: fix sync.py –sync-flags

    The help text used single quotes for the JSON example instead of
    the required double quotes. Running without –sync-flags was broken
    because of trying to parse the empty string as JSON.

  • command line: revise usability checking of datastores

    When configuring a new sync config, the command line checks whether a
    datastore is usable before enabling it. If no datastores were listed
    explicitly, only the usable ones get enabled. If unusable datastores
    were explicitly listed, the entire configure operation fails.

    This check was based on listing databases, which turned out to be too
    unspecific for the WebDAV backend: when “database” was set to some URL
    which is good enough to list databases, but not a database URL itself,
    the sources where configured with that bad URL.

    Now a new SyncSource::isUsable() operation is used, which by default
    just falls back to calling the existing Operations::m_isEmpty. In
    practice, all sources either check their config in open() or the
    m_isEmpty operation, so the source is usable if no error is
    enountered.

    For WebDAV, the usability check is skipped because it would require
    contacting a remote server, which is both confusing (why does a local
    configure operation need the server?) and could fail even for valid
    configs (server temporarily down). The check was incomplete anyway
    because listing databases gave a fixed help text response when no
    credentials were given. For usability checking that should have
    resulted in “not usable” and didn’t.

    The output during the check was confusing: it always said “listing
    databases” without giving a reason why that was done. The intention
    was to give some feedback while a potentially expensive operation
    ran. Now the isUsable() method itself prints “checking usability” if
    (and only if!) such a check is really done.

    Sometimes datastores were checked even when they were about to be
    configure as “disabled” already. Now checking such datastores is
    skipped.

  • EDS: memo syncing as iCalendar 2.0 (FDO #52714)

    When syncing memos with a peer which also supports iCalendar 2.0 as
    data format, the engine will now pick iCalendar 2.0 instead of
    converting to/from plain text. The advantage is that some additional
    properties like start date and categories can also be synchronized.

    The code is a lot simpler, too, because the EDS specific iCalendar 2.0
    <-> text conversion code can be removed.

  • datatypes: text/calendar+plain revised heuristic

    When sending a VEVENT, DESCRIPTION was set to the SUMMARY if empty. This may
    have been necessary for some peers, but for notes (= VJOURNAL) we don’t know
    that (hasn’t been used in the past) and don’t want to alter the item
    unnecessarily, so skip that part and allow empty DESCRIPTION.

    When receiving a plain text note, the “text/calendar+plain” type
    used to store the first line as summary and the rest as description.
    This may be correct in some cases and wrong in others.

    The EDS backend implemented a different heuristic: there the first
    line is copied into the summary and stays in the description. This
    makes a bit more sense (the description alone is always enough to
    understand the note). Therefore and to avoid behavioral changes
    for EDS users when switching the EDS backend to use text/calendar+plain,
    the engine now uses the same approach.

  • source -> datastore rename, improved terminology

    The word “source” implies reading, while in fact access is read/write.
    “datastore” avoids that misconception. Writing it in one word emphasizes
    that it is single entity.

    While renaming, also remove references to explicit –*-property
    parameters. The only necessary use today is “–sync-property ?”
    and “–datastore-property ?”.

    –datastore-property was used instead of the short –store-property
    because “store” might be mistaken for the verb. It doesn’t matter
    that it is longer because it doesn’t get typed often.

    –source-property must remain valid for backward compatility.

    As many user-visible instances of “source” as possible got replaced in
    text strings by the newer term “datastore”. Debug messages were left
    unchanged unless some regex happened to match it.

    The source code will continue to use the old variable and class names
    based on “source”.

    Various documentation enhancements:
    Better explain what local sync is and how it involves two sync
    configs. “originating config” gets introduces instead of just
    “sync config”.

    Better explain the relationship between contexts, sync configs,
    and source configs (”a sync config can use the datastore configs in
    the same context”).

    An entire section on config properties in the terminology
    section. “item” added (Todd Wilson correctly pointed out that it was
    missing).

    Less focus on conflict resolution, as suggested by Graham Cobb.

    Fix examples that became invalid when fixing the password
    storage/lookup mechanism for GNOME keyring in 1.4.

    The “command line conventions”, “Synchronization beyond SyncML” and
    “CalDAV and CardDAV” sections were updated. It’s possible that the
    other sections also contain slightly incorrect usage of the
    terminology or are simply out-dated.

  • local sync: allow config name in syncURL=local://

    Previously, only syncURL=local://@ was allowed and used
    the “target-config@context name” config as target side in the local
    sync.

    Now “local://config-name@context-name” or simply “local://config-name”
    are also allowed. “target-config” is still the fallback if only a
    context is give.

    It also has one more special meaning: “–configure
    target-config@google” will pick the “Google” template automatically
    because it knows that the intention is to configure the target side
    of a local sync. It does not know that when using some other name
    for the config, in which case the template (if needed) must be
    specified explicitly.

    The process name in output from the target side now also includes the
    configuration name if it is not the default “target-config”.

  • Google: remove SyncML template, combine CalDAV/CardDAV

    Google has turned off their SyncML server, so the corresponding
    “Google Contacts” template became useless and needs to be removed. It
    gets replaced by a “Google” template which combines the three
    different URLs currently used by Google for CalDAV/CardDAV.

    This new template can be used to configure a “target-config@google”
    with default calendar and address book database already enabled. The
    actual URL of these databases will be determined during the first
    sync using them.

    The template relies on the WebDAV backend’s new capability to search
    multiple different entries in the syncURL property for databases. To
    avoid listing each calendar twice (once for the legacy URL, once with
    the new one) when using basic username/password authentication, the
    backend needs a special case for Google and detect that the legacy URL
    does not need to be checked.

  • config: allow storing credentials for email address

    When configuring a WebDAV server with username = email address and no
    URL (which is possible if the server supports service discovery via
    the domain in the email address), then storing the credentials in the
    GNOME keyring used to fail with “cannot store password in GNOME
    keyring, not enough attributes”.

    That is because GNOME keyring seemed to get confused when a network
    login has no server name and some extra safeguards were added to
    SyncEvolution to avoid this.

    To store the credentials in the case above, the email address now gets
    split into user and domain part and together get used to look up the
    password.

Upgrading from releases <= 1.3.99.4:

If the value of “username/databaseUser/proxyUser” contains a colon,
the “user:” prefix must be added to the value, to continue treating it
like a plain user name and not some reference to an unknown identity
provider (like “id:”, “goa:”, “signon:”, etc.).

The lookup of passwords in GNOME Keyring was updated slightly in
1.3.99.5. It may be necessary to set passwords anew if the old one is
no longer found.

Upgrading from release 1.2.x:

The sync format of existing configurations for Mobical (aka Everdroid)
must be updated manually, because the server has encoding problems when
using vCard 3.0 (now the default for Evolution contacts):
syncevolution –configure \
syncFormat=text/x-vcard \
mobical addressbook

The Funambol template explicitly enables usage of the
“refresh-from-server” sync mode to avoid getting throttled with 417
‘retry later’ errors. The same must be added to existing configs
manually:
syncevolution –configure \
enableRefreshSync=TRUE \
funambol

Upgrading from releases before 1.2:

Old configurations can still be read. But writing, as it happens
during a sync, must migrate the configuration first. Releases >= 1.2
automatically migrates configurations. The old configurations
will still be available (see “syncevolution –print-configs”) but must
be renamed manually to use them again under their original names with
older SyncEvolution releases.

Source, Installation, Further information

Source code bundles for users are available in
http://downloads.syncevolution.org/syncevolution/sources
and the original source is in the git repositories.

i386, lpia and amd64 binaries for Debian-based distributions are
available via the “unstable” syncevolution.org repository. Add the
following entry to your /apt/source.list:

Then install “syncevolution-evolution”, “syncevolution-kde” and/or
“syncevolution-activesync”.

These binaries include the “sync-ui” GTK GUI and were compiled for
Ubuntu 10.04 LTS (Lucid), except for ActiveSync binaries which were compiled for Debian Wheezy, Ubuntu Saucy and Ubuntu Trusty. A backend
for Ubuntu Online Accounts was compiled on Ubuntu Saucy. The packages mentioned above are meta-packages which pull in suitable packages matching the distro during installation.

Older distributions like Debian 4.0 (Etch) can no longer be supported
with precompiled binaries because of missing libraries, but the source
still compiles when not enabling the GUI (the default).

The same binaries are also available as .tar.gz and .rpm archives in
the download directories. In contrast
to 0.8.x archives, the 1.x .tar.gz archives have to be unpacked and the
content must be moved to /usr, because several files would not be found
otherwise.

After installation, follow the getting started steps. More specific HOWTOs can be found in the Wiki.