Engine: Do not emit optimistic change notifications unless the local value is different
Depends on !59 (merged)
Currently when using the optimistic "fast" API, when a client requests a write to the database, changed signals are emitted to the clients of the engine process even if the writes did not result in the engine process's copy of the database changing values.
This results in infinite loops when client code such as gnome-shell and extensions perform writes as a result of changed notifications without checking if the new value is different from the old value. For example, it causes bugs like this: https://bugzilla.gnome.org/show_bug.cgi?id=782688
Client code can avoid this problem by keeping a reference to the current value of any watched setting and not performing writes as a result of changed signals when the new value is the same as the old value. This is impractical to fix (there are hundreds of places in gnome-shell and various extensions which do this). It is also a problem that if a single shell extension that does not perform this optimisation, the entire shell goes into an infinite loop and hangs or crashes. The changed signal should not be sent in the first place unless they key has changed, and developers working with high level languages such as Javascript should not be responsible for handling the consequences of race conditions in multithreaded C code.
This change still sends the write request to the writer service in all cases, but does not emit local optimistic changed signals unless the changeset results in some value in the database being different to what it previously was. This breaks the infinite loops while still preserving the ability of the writer process/DBus to serialize all writes (and possibly still emit changed signals if the canonical copy of the database is changed by the write).
See existing discussion on bugzilla here: https://bugzilla.gnome.org/show_bug.cgi?id=789639