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:
parent
3ae92086cd
commit
a14b12b8d4
|
@ -321,7 +321,7 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int,
|
||||||
|
|
||||||
var deletedAlbumIDs []int = nil
|
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 {
|
if err := tx.Raw("DELETE FROM user_albums WHERE user_id = ? AND album_id = ?", userID, albumID).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -346,12 +346,12 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup if no user owns the album anymore
|
// Cleanup if no user owns the album anymore
|
||||||
var count int
|
var userAlbumCount int
|
||||||
if err := tx.Raw("SELECT COUNT(user_id) FROM user_albums WHERE album_id = ?", albumID).Scan(&count).Error; err != nil {
|
if err := tx.Raw("SELECT COUNT(user_id) FROM user_albums WHERE album_id = ?", albumID).Scan(&userAlbumCount).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if count == 0 {
|
if userAlbumCount == 0 {
|
||||||
deletedAlbumIDs = append(childAlbumIDs, albumID)
|
deletedAlbumIDs = append(childAlbumIDs, albumID)
|
||||||
childAlbumIDs = nil
|
childAlbumIDs = nil
|
||||||
|
|
||||||
|
@ -360,17 +360,13 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int,
|
||||||
deletedAlbumIDs = nil
|
deletedAlbumIDs = nil
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := face_detection.GlobalFaceDetector.ReloadFacesFromDatabase(tx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if transactionError != nil {
|
||||||
return nil, err
|
return nil, transactionError
|
||||||
}
|
}
|
||||||
|
|
||||||
if deletedAlbumIDs != nil {
|
if deletedAlbumIDs != nil {
|
||||||
|
@ -382,6 +378,11 @@ func (r *mutationResolver) UserRemoveRootAlbum(ctx context.Context, userID int,
|
||||||
return nil, err
|
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
|
return &album, nil
|
||||||
|
|
|
@ -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
|
// 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 {
|
func (fd *FaceDetector) DetectFaces(db *gorm.DB, media *models.Media) error {
|
||||||
if err := tx.Model(media).Preload("MediaURL").First(&media).Error; err != nil {
|
if err := db.Model(media).Preload("MediaURL").First(&media).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ func (fd *FaceDetector) DetectFaces(tx *gorm.DB, media *models.Media) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, face := range faces {
|
for _, face := range faces {
|
||||||
fd.classifyFace(tx, &face, media, thumbnailPath)
|
fd.classifyFace(db, &face, media, thumbnailPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -126,7 +126,7 @@ func (fd *FaceDetector) classifyDescriptor(descriptor face.Descriptor) int32 {
|
||||||
return int32(fd.rec.ClassifyThreshold(descriptor, 0.2))
|
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()
|
fd.mutex.Lock()
|
||||||
defer fd.mutex.Unlock()
|
defer fd.mutex.Unlock()
|
||||||
|
|
||||||
|
@ -153,18 +153,18 @@ func (fd *FaceDetector) classifyFace(tx *gorm.DB, face *face.Face, media *models
|
||||||
ImageFaces: []models.ImageFace{imageFace},
|
ImageFaces: []models.ImageFace{imageFace},
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tx.Create(&faceGroup).Error; err != nil {
|
if err := db.Create(&faceGroup).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
log.Println("Found match")
|
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
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,10 +75,11 @@ func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *gorm.DB) {
|
||||||
|
|
||||||
album_has_changes := false
|
album_has_changes := false
|
||||||
for count, media := range albumMedia {
|
for count, media := range albumMedia {
|
||||||
// tx, err := db.Begin()
|
processing_was_needed := false
|
||||||
|
|
||||||
transactionError := db.Transaction(func(tx *gorm.DB) error {
|
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 {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "failed to process photo (%s)", media.Path)
|
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),
|
Content: fmt.Sprintf("Processed media at %s", media.Path),
|
||||||
Progress: &progress,
|
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
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if transactionError != nil {
|
if transactionError != nil {
|
||||||
ScannerError("Failed to begin database transaction: %s", transactionError)
|
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)
|
cleanup_errors := CleanupMedia(db, album.ID, albumMedia)
|
||||||
|
|
Loading…
Reference in New Issue