1
Fork 0

Fix bug where DetectFaces would be called with the wrong media.

This happend because the go routine did not capture the media variable,
and so the it would change before the go routine could start
and call the DetectFaces function.
This commit is contained in:
viktorstrate 2021-03-16 22:27:27 +01:00
parent 3ae92086cd
commit a14b12b8d4
No known key found for this signature in database
GPG Key ID: 3F855605109C1E8A
3 changed files with 30 additions and 27 deletions

View File

@ -321,7 +321,7 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int,
var deletedAlbumIDs []int = nil
err := r.Database.Transaction(func(tx *gorm.DB) error {
transactionError := r.Database.Transaction(func(tx *gorm.DB) error {
if err := tx.Raw("DELETE FROM user_albums WHERE user_id = ? AND album_id = ?", userID, albumID).Error; err != nil {
return err
}
@ -346,12 +346,12 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int,
}
// Cleanup if no user owns the album anymore
var count int
if err := tx.Raw("SELECT COUNT(user_id) FROM user_albums WHERE album_id = ?", albumID).Scan(&count).Error; err != nil {
var userAlbumCount int
if err := tx.Raw("SELECT COUNT(user_id) FROM user_albums WHERE album_id = ?", albumID).Scan(&userAlbumCount).Error; err != nil {
return err
}
if count == 0 {
if userAlbumCount == 0 {
deletedAlbumIDs = append(childAlbumIDs, albumID)
childAlbumIDs = nil
@ -360,17 +360,13 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int,
deletedAlbumIDs = nil
return err
}
if err := face_detection.GlobalFaceDetector.ReloadFacesFromDatabase(tx); err != nil {
return err
}
}
return nil
})
if err != nil {
return nil, err
if transactionError != nil {
return nil, transactionError
}
if deletedAlbumIDs != nil {
@ -382,6 +378,11 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int,
return nil, err
}
}
// Reload faces as media might have been deleted
if err := face_detection.GlobalFaceDetector.ReloadFacesFromDatabase(r.Database); err != nil {
return nil, err
}
}
return &album, nil

View File

@ -84,8 +84,8 @@ func (fd *FaceDetector) ReloadFacesFromDatabase(db *gorm.DB) error {
}
// DetectFaces finds the faces in the given image and saves them to the database
func (fd *FaceDetector) DetectFaces(tx *gorm.DB, media *models.Media) error {
if err := tx.Model(media).Preload("MediaURL").First(&media).Error; err != nil {
func (fd *FaceDetector) DetectFaces(db *gorm.DB, media *models.Media) error {
if err := db.Model(media).Preload("MediaURL").First(&media).Error; err != nil {
return err
}
@ -116,7 +116,7 @@ func (fd *FaceDetector) DetectFaces(tx *gorm.DB, media *models.Media) error {
}
for _, face := range faces {
fd.classifyFace(tx, &face, media, thumbnailPath)
fd.classifyFace(db, &face, media, thumbnailPath)
}
return nil
@ -126,7 +126,7 @@ func (fd *FaceDetector) classifyDescriptor(descriptor face.Descriptor) int32 {
return int32(fd.rec.ClassifyThreshold(descriptor, 0.2))
}
func (fd *FaceDetector) classifyFace(tx *gorm.DB, face *face.Face, media *models.Media, imagePath string) error {
func (fd *FaceDetector) classifyFace(db *gorm.DB, face *face.Face, media *models.Media, imagePath string) error {
fd.mutex.Lock()
defer fd.mutex.Unlock()
@ -153,18 +153,18 @@ func (fd *FaceDetector) classifyFace(tx *gorm.DB, face *face.Face, media *models
ImageFaces: []models.ImageFace{imageFace},
}
if err := tx.Create(&faceGroup).Error; err != nil {
if err := db.Create(&faceGroup).Error; err != nil {
return err
}
} else {
log.Println("Found match")
if err := tx.First(&faceGroup, int(match)).Error; err != nil {
if err := db.First(&faceGroup, int(match)).Error; err != nil {
return err
}
if err := tx.Model(&faceGroup).Association("ImageFaces").Append(&imageFace); err != nil {
if err := db.Model(&faceGroup).Association("ImageFaces").Append(&imageFace); err != nil {
return err
}
}

View File

@ -75,10 +75,11 @@ func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *gorm.DB) {
album_has_changes := false
for count, media := range albumMedia {
// tx, err := db.Begin()
processing_was_needed := false
transactionError := db.Transaction(func(tx *gorm.DB) error {
processing_was_needed, err := ProcessMedia(tx, media)
log.Printf("Process media transaction enter (%s)", media.Path)
processing_was_needed, err = ProcessMedia(tx, media)
if err != nil {
return errors.Wrapf(err, "failed to process photo (%s)", media.Path)
}
@ -93,22 +94,23 @@ func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *gorm.DB) {
Content: fmt.Sprintf("Processed media at %s", media.Path),
Progress: &progress,
})
if media.Type == models.MediaTypePhoto {
go func() {
if err := face_detection.GlobalFaceDetector.DetectFaces(tx, media); err != nil {
ScannerError("Error detecting faces in image (%s): %s", media.Path, err)
}
}()
}
}
log.Printf("Process media transaction exit (%s)", media.Path)
return nil
})
if transactionError != nil {
ScannerError("Failed to begin database transaction: %s", transactionError)
}
if processing_was_needed && media.Type == models.MediaTypePhoto {
go func(media *models.Media) {
if err := face_detection.GlobalFaceDetector.DetectFaces(db, media); err != nil {
ScannerError("Error detecting faces in image (%s): %s", media.Path, err)
}
}(media)
}
}
cleanup_errors := CleanupMedia(db, album.ID, albumMedia)