Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Purge issue fix: Lp1821514 #2065

Merged
merged 4 commits into from
Mar 29, 2019
Merged

Purge issue fix: Lp1821514 #2065

merged 4 commits into from
Mar 29, 2019

Conversation

daschuer
Copy link
Member

@daschuer daschuer commented Mar 25, 2019

Fix issues with purged tracks.

Now purged tracks are kept in cache as usual. This is required to have only a single reference to a file.
This is relevant if the track is re-added, before the track is pushed from the cache.
To keep a consistent state, the track id and date added is removed.

https://bugs.launchpad.net/mixxx/+bug/1821514

… is already used for missing entries, fixing lp1821514
This is required since they are not anymore part of the libary.
@daschuer daschuer added this to the 2.1.x milestone Mar 25, 2019
@daschuer
Copy link
Member Author

daschuer commented Mar 25, 2019

Not sure if this one fixes the pending drag and drop issue as well. There is a chance ..
#2045

@daschuer daschuer changed the title Lp1821514 Purge issue fix: Lp1821514 Mar 26, 2019
@uklotzde
Copy link
Contributor

Messing up the identity of an existing object during its lifetime is the wrong approach.

Why not mark both the database record as well as the track object as to-be-deleted? If it is rediscovered by the library scanner the track object keeps its ID and only the deletion flags need to be reset. If the track object is finally purged from the cache and the deletion flag is still set then it needs to be deleted from the database instead of updated.

@uklotzde
Copy link
Contributor

Only tracks that are not referenced by GlobalTrackCache are allowed to be physically deleted from the database when purged. Otherwise they would lose their ID when rediscovered.

@daschuer
Copy link
Member Author

I have also considered a delete flag solution like you have proposed. I have actually started to implement it, but I have decided against, because of two reasons: The code involved becomes more complex because the additional case handling of a cached track and because the user expect that the track disappears instantly.

Then I realized that the "messing up" is not a real problem, because we logical only undo the library "add". Mixxx can handle Tracks without an ID. The ID is set during the library addition. When purging a track we just undo this and go back to the original state.
If the user adds the track again it gets a new ID as usual this is the intended behavior. The same happens if the track disappears from the cache and is added back. The track is always referenced by its location as required to avoid duplicated Track objects for one device

@@ -698,6 +698,11 @@ void Track::initId(TrackId id) {
// generated by the Database itself.
}

void Track::resetId() {
QMutexLocker lock(&m_qMutex);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't make sense, the id is not protected by the lock. I would recommend to adopt the same strategy as for initId() which is also invoked only from GlobalTrackCache. The ID of a track must only be modified by GlobalTrackCache while locked!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand your point here. The call stacks of initId() and resetId() are very similar both private and both used the lock. We can of cause get rid of the lock in both cases because both are done from the GUI aka library thread and are int which is written atomic.
What could be improved here?

Copy link
Contributor

@uklotzde uklotzde Mar 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ups, sorry. I must have had an earlier state of the code in my mind. It's the dirty flag that doesn't need to be set. The locking seems to be correct!

@@ -327,6 +327,8 @@ class Track : public QObject {
// GlobalTrackCacheResolver!
void initId(TrackId id); // write-once
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write-once is no longer true

initId() and resetId() and share the same restrictions mentioned in the comment above!

if (m_tracksById.end() != trackById) {
Track* track = trackById->second->getPlainPtr();
track->resetId();
track->setDateAdded(QDateTime());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resetting the date does definitely not belong here, completely wrong context and abstraction level.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is moved here, because normally we have no track object when purging a track. It is a database only action that operates with track IDs only. Only at this point if we have found the ID in the cache, we have access to the track object.

We can solve the abstraction issue by instantiate a track object before purging it, but that is just extra CPU and DB reads. Alternative, we may not reset The date added and remove the debug assert expecting a NULL date before adding.

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then let's keep the date unmodified instead of violating abstraction rules. The Track object needs to be aware of the use case that it might be re-added. Please log a message on level INFO if that happens.

@daschuer
Copy link
Member Author

Done.

@uklotzde
Copy link
Contributor

LGTM. Thank you for handling this edge case!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants