After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 755181 - filesystem: weird content-changed notifications
filesystem: weird content-changed notifications
Status: RESOLVED FIXED
Product: grilo
Classification: Other
Component: plugins
unspecified
Other Linux
: High critical
: ---
Assigned To: grilo-maint
grilo-maint
Depends on:
Blocks: 755793
 
 
Reported: 2015-09-17 20:02 UTC by Xavier Claessens
Modified: 2015-09-29 14:37 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
filesystem: avoid duplicate change notification (1.30 KB, patch)
2015-09-17 20:02 UTC, Xavier Claessens
none Details | Review
filesystem: avoid duplicate change notifications (7.49 KB, patch)
2015-09-18 18:30 UTC, Xavier Claessens
none Details | Review
filesystem: avoid duplicate change notifications (7.37 KB, patch)
2015-09-24 13:57 UTC, Xavier Claessens
committed Details | Review
filesystem: Give the media in notifications, not its parent dir (3.22 KB, patch)
2015-09-25 13:27 UTC, Xavier Claessens
committed Details | Review

Description Xavier Claessens 2015-09-17 20:02:16 UTC
When I create a new file /home/xclaesse/file.mp3 I get 2 "content-changed" signals:

1) GRL_CONTENT_ADDED for file:///home/xclaesse
2) GRL_CONTENT_CHANGED for file:///home/xclaesse

I think the first should GRL_CONTENT_ADDED for file:///home/xclaesse/file.mp3 and the 2nd GRL_CONTENT_CHANGED for file:///home/xclaesse.
Comment 1 Xavier Claessens 2015-09-17 20:02:36 UTC
Created attachment 311585 [details] [review]
filesystem: avoid duplicate change notification

Creating a new file was emitting 2 signals, one with
GRL_CONTENT_ADDED followed by one with GRL_CONTENT_CHANGED,
for the same path.
Comment 2 Xavier Claessens 2015-09-17 20:11:53 UTC
Hm the fact that it emits a ADDED even on the parent directory seems intentional judging by the function name notify_parent_change(). It's weird, should it be changed?
Comment 3 Bastien Nocera 2015-09-18 10:37:28 UTC
I'll let Juan review this. The patch looks fine, but I'm not sure what the behaviour is supposed to be.

Juan, could you explain how the notification is supposed to behave so that we can document it?
Comment 4 Xavier Claessens 2015-09-18 16:07:09 UTC
My patch above is not enough, that function is not handling G_FILE_MONITOR_EVENT_CHANGED case. I suspect it was a typo s/CHANGES_DONE_HINT/CHANGED/.

Reading more grl-filesystem.c I see 2 other potential issue:

1) Every time recursive_operation_initialize() is called it creates a new GFileMonitor for all chosen URIs. So you'll get lots of duplicated signals.

2) Let's say /foo/bar is a directory, it will install a monitor for /foo and /foo/bar. When deleting that directory both monitors will emit signal telling /foo/bar is deleted, leading to duplicated "content-changed" signal.
Comment 5 Xavier Claessens 2015-09-18 18:30:40 UTC
Created attachment 311649 [details] [review]
filesystem: avoid duplicate change notifications

- Make sure to have only one GFileMonitor per directory

 - When deleting a directory avoid having both monitors
   (deleted dir's and its parent's) notifying it.

 - Fix typo causing notification when a monitor emits
   G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT which happens
   after each set of changes.
Comment 6 Xavier Claessens 2015-09-18 18:33:25 UTC
Oh, that patch also fix the inverted logic of g_file_equal(), it's not a cmp function that return 0 when equal...
Comment 7 Bastien Nocera 2015-09-24 12:56:14 UTC
Review of attachment 311649 [details] [review]:

::: src/filesystem/grl-filesystem.c
@@ +962,3 @@
+                            G_FILE_QUERY_INFO_NONE,
+                            NULL, NULL);
+  if (!info || !file_is_valid_content (info, TRUE, NULL))

file_is_valid_content() in fast mode will make most files (even the ones that aren't known) into valid media. Do we want that?

@@ +1008,3 @@
+  g_hash_table_iter_init (&iter, fs_source->priv->monitors);
+  while (g_hash_table_iter_next (&iter, NULL, &value))
+    g_file_monitor_cancel (value);

Do we want to replace the hash table's GDestroyNotify for that member? cancel and unref rather than just unref, as there isn't a case where we add a monitor to the hash table without starting it.
Comment 8 Xavier Claessens 2015-09-24 13:56:53 UTC
(In reply to Bastien Nocera from comment #7)
> Review of attachment 311649 [details] [review] [review]:
> 
> ::: src/filesystem/grl-filesystem.c
> @@ +962,3 @@
> +                            G_FILE_QUERY_INFO_NONE,
> +                            NULL, NULL);
> +  if (!info || !file_is_valid_content (info, TRUE, NULL))
> 
> file_is_valid_content() in fast mode will make most files (even the ones
> that aren't known) into valid media. Do we want that?

I don't know, it was already doing that before my patch, I'm just rearranging the code in a way easier to understand. I guess it's better to notify too much when in doubt?

> @@ +1008,3 @@
> +  g_hash_table_iter_init (&iter, fs_source->priv->monitors);
> +  while (g_hash_table_iter_next (&iter, NULL, &value))
> +    g_file_monitor_cancel (value);
> 
> Do we want to replace the hash table's GDestroyNotify for that member?
> cancel and unref rather than just unref, as there isn't a case where we add
> a monitor to the hash table without starting it.

Actually unref is enough, g_file_monitor_dispose() will cancel it for us.
Comment 9 Xavier Claessens 2015-09-24 13:57:55 UTC
Created attachment 312058 [details] [review]
filesystem: avoid duplicate change notifications

- Make sure to have only one GFileMonitor per directory

 - When deleting a directory avoid having both monitors
   (deleted dir's and its parent's) notifying it.

 - Fix typo causing notification when a monitor emits
   G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT which happens
   after each set of changes.
Comment 10 Bastien Nocera 2015-09-24 14:03:22 UTC
Review of attachment 312058 [details] [review]:

Sure.
Comment 11 Xavier Claessens 2015-09-24 14:35:02 UTC
Comment on attachment 312058 [details] [review]
filesystem: avoid duplicate change notifications

Attachment 312058 [details] pushed as 32c4942 - filesystem: avoid duplicate change notifications
Comment 12 Xavier Claessens 2015-09-24 14:37:07 UTC
Still has the open question: should it notify with a GrlMedia that has the URL of the parent directory, or with the media itself. IMHO it's much more useful to have the media that got added than the parent directory with no clue what media got added...
Comment 13 Juan A. Suarez Romero 2015-09-25 08:03:36 UTC
Unfortunately, I think the semantic of notifications is not very well defined :/


We added the ADD in the parent because there were sources that can't really notify about a specific element added, but just that the container got a new element.

So we sent the ADD in the parent with the hope the client would re-browse the parent again.


But in other cases the source could send the ADD with the specific added element.

Of course, there's an ambiguity when the added element is container too, because the client is not able to know if the added element is a parent or a specific element.

I think someone suggested to use the semantic of using always the parent, and thus we used that in the Filesystem. But with time, seems we forgot about it (probably because there are very good reasons to notify with the specific element added) and we started again to notify the added element.

We need to have a way to cover both cases: a way of notifying about the exact element, and also a way to notify a change happened in parent, but can't send the specific element sent.

For this specific bug, I'm fine with just sending the media itself.


For a proposal (and taking in account we are in API break period), I would suggest to slightly change the grl_source_notify_change(), as well as the "content-changed" signal.

Both contains a "location_unknown" property. Its goal was for telling the client where the change happens.

Le't figure out a browse hierarchy like this:

(root) -> Artist -> Artist1 -> Album1 -> Song1

When getting a "content-changed" with "Artist", if location_unknown == FALSE it meant that the change happened inside Artist content; but if location_unknown == TRUE, meant source can't tell where exactly is happening the change; could be in Artist, Artist1, Album1 or Song1.

This is most useful for sources that only can tell "I changed" but not exactly where. In this case, we would send the content-changed notification with the "root" and location_unknown == TRUE.


So mostly I propose a slightly modification and change the location_unknown by an enum, with 3 values (let's search for better names):

* GRL_CHANGED_ELEMENT: the element received is the one that has changed (that is, it was modified, removed or added).

* GRL_CHANGED_CHILDREN: the element received is a container, and some of its children has changed (modified, removed or added).

* GRL_CHANGED_OFFSPRING: the element received is a container, and children or any element below the hierarchy has changed (modified, removed, or added).

As the example above, getting "content-changed" with "Artist1" would mean the following, depending on the enum.

* GRL_CHANGED_ELEMENT: Artist1 was added, or removed, or some of its properties changed.

* GRL_CHANGED_CHILDREN: An album (for instance, Album1) has been added, changed or removed.

* GRL_CHANGED_OFFSPRING: Either an album or a song has been added, changed or removed.


This would fix the ambiguity in the notification, as well as allowing sources to notify with the degree they can.
Comment 14 Xavier Claessens 2015-09-25 13:27:48 UTC
Created attachment 312143 [details] [review]
filesystem: Give the media in notifications, not its parent dir
Comment 15 Xavier Claessens 2015-09-25 13:30:13 UTC
My understanding is that when location_unknown==FALSE we give the media itself. When it's TRUE it means something changed in that hierarchy and apps should re-browse the whole thing because we don't know exactly what changed. That would make sense IMHO. In the FS case we know the exact media that got added/removed/changed.
Comment 16 Juan A. Suarez Romero 2015-09-25 13:57:34 UTC
(In reply to Xavier Claessens from comment #15)
> My understanding is that when location_unknown==FALSE we give the media
> itself. When it's TRUE it means something changed in that hierarchy and apps
> should re-browse the whole thing because we don't know exactly what changed.
> That would make sense IMHO. In the FS case we know the exact media that got
> added/removed/changed.


Actually no. The meaning was if the change was in the container's direct children or in any element below the hierarchy.


But we never made explicit if you get "content-changed(A1, ADDED)", if it means A1 was added, or an elemement was added to container A1. We just thought that would be documented for each source.

So the proposal tries to fix this ambiguity.
Comment 17 Xavier Claessens 2015-09-25 14:46:56 UTC
if /foo/bar is added, and the backend knows it, I don't see how it can possibly help anyone to tell "something got added in /foo, I'll let you browse everything again to find out what". That seems just plain wrong to me.

If however the backend doesn't know exactly what got added, then put a flag that it's unknown and app should browse again instead.

That seems pretty simple to me, no complicated API, not even an API change needed. I don't understand why you need all those changes tbh.
Comment 18 Juan A. Suarez Romero 2015-09-25 15:16:11 UTC
(In reply to Xavier Claessens from comment #17)
> if /foo/bar is added, and the backend knows it, I don't see how it can
> possibly help anyone to tell "something got added in /foo, I'll let you
> browse everything again to find out what". That seems just plain wrong to me.
> 

(In reply to Xavier Claessens from comment #17)
> if /foo/bar is added, and the backend knows it, I don't see how it can
> possibly help anyone to tell "something got added in /foo, I'll let you
> browse everything again to find out what". That seems just plain wrong to me.
> 

Because some sources only tells you that something was added or removed, but not exactly what. So if you want to notify exactly what, your grilo source need to calculate what changed, which can imply lot of computation.


> If however the backend doesn't know exactly what got added, then put a flag
> that it's unknown and app should browse again instead.
> 

Yes, correct.

> That seems pretty simple to me, no complicated API, not even an API change
> needed. I don't understand why you need all those changes tbh.

Because you still miss a case: source knows that something changed but not what or where.

In this case we were notifying content-changed in the root, and using the location_unknown=TRUE, to tell client that something changed in the source.


In any case, it's up to the client if it wants to re-browse or not. In some cases clients preferred to re-browse, instead of keeping a list of elements that should be added/removed on each notification.

The proposal I did is almost the same we have now, except the boolean is now an enum to cover the 3 cases.
Comment 19 Juan A. Suarez Romero 2015-09-26 21:49:30 UTC
There's also another point of view: client side.

Let's figure out we are browsing a source, and showing a list of medias from a container (eg, list of songs from an album).

And we get a content-removed signal. What to do? We search the media in the list of medias we are showing, and remove it.


But what we do when the signal is a content added? First step is knowing if the element belongs to the container we are showing. The received media doesn't contain the parent, so it isn't easy. Maybe if you know the source you're browsing and know how the content is structured in the hierarchy, you can guess the parent. But in general, each source design its own structure, so you can't find if the element should be shown.

Well, and even if you are able to do, this complicates the paginated browsing. Because adding a new element requires to adapt the count and offset to avoid missing or having duplicated elements in the list.

This is the reason why sometimes it is better to just forget about the added element and rebrowse the container. And I think this is why some sources were sending the parent instead of the element itself when content was added.

Maybe what we need is sending both the element added (or removed or changed), and also the parent (the source should know for each element what parent should have). This would make easier for clients that just discard all the content and re-browse, as well as those that prefer to add the element to the list of medias.
Comment 20 Xavier Claessens 2015-09-29 14:22:03 UTC
So in the end, I'm not sure about attachment #312143 [details], is it rejected?
Comment 21 Juan A. Suarez Romero 2015-09-29 14:30:37 UTC
I'm fine with it.

Probably we need to redesign this notification system to avoid the mentioned problems.
Comment 22 Xavier Claessens 2015-09-29 14:33:59 UTC
Attachment 312143 [details] pushed as 5e99456 - filesystem: Give the media in notifications, not its parent dir
Comment 23 Xavier Claessens 2015-09-29 14:37:02 UTC
I've opened bug #755793 for changing content-changed API.