Skip to content

fix: asset update race condition#16901

Closed
danieldietzler wants to merge 1 commit intomainfrom
fix/asset-update-race-condition
Closed

fix: asset update race condition#16901
danieldietzler wants to merge 1 commit intomainfrom
fix/asset-update-race-condition

Conversation

@danieldietzler
Copy link
Copy Markdown
Member

Fixes #16747; a race condition between updating an asset and metadata extraction:

  1. Asset gets uploaded, METADATA_EXTRACTION is queued
  2. Asset exif data is updated using the API; SIDECAR_WRITE is queued
  3. METADATA_EXTRACTION is scheduled, updating and overriding all changes to the asset in the database
  4. SIDECAR_WRITE is scheduled, but the changes are already lost

@danieldietzler danieldietzler requested a review from jrasm91 March 16, 2025 12:21
@danieldietzler danieldietzler force-pushed the fix/asset-update-race-condition branch 6 times, most recently from fcd2a7f to d0f1793 Compare March 16, 2025 14:06
Comment on lines +176 to +186
const { exifInfo } = (await this.assetRepository.getById(asset.id, { exifInfo: true })) || {};
await this.handleSidecarWrite({
id: asset.id,
description: exifInfo?.description,
dateTimeOriginal: exifInfo?.dateTimeOriginal?.toISOString(),
latitude: exifInfo?.latitude ?? undefined,
longitude: exifInfo?.longitude ?? undefined,
rating: exifInfo?.rating ?? undefined,
tags: true,
});
asset = (await this.assetRepository.getById(asset.id, { faces: { person: false } }))!;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This fetches the same asset on each line (handleSidecarWrite internally fetches the asset). Could you make it do one DB call including exifInfo, face and tag relations?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

My thinking was that this very rarely needs to run in the first place, so I didn't want to slow down the "happy path" by joining exif there. Either way I need at least two calls total since I need to get the sidecar path after the sidecar file got written.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, I meant one DB call for the "sad path" here vs 3. I agree joining exif for the main job wouldn't be ideal.

Copy link
Copy Markdown
Member Author

@danieldietzler danieldietzler Mar 16, 2025

Choose a reason for hiding this comment

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

Right, but I need exifInfo before the sidecar write and I need the sidecar path (that in most cases doesn't exist before) after the sidecar write 😅

Copy link
Copy Markdown
Member

@mertalev mertalev Mar 16, 2025

Choose a reason for hiding this comment

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

I don't get it. handleSidecarWrite just checks 1) if the asset exists and 2) what its sidecar path is, and you need exifInfo to update the sidecar. What part of this requires multiple queries?

To be clear, I'm suggesting you can make handleSidecarWrite's body a private method instead of calling it like it's a job.

@niieani
Copy link
Copy Markdown

niieani commented Oct 12, 2025

was wondering if this PR could get some love? would love to see this fixed. 🙇

@meesfrensel
Copy link
Copy Markdown
Collaborator

Superseded by #24384 @danieldietzler ?

@danieldietzler
Copy link
Copy Markdown
Member Author

Superseded by #24384

@meesfrensel meesfrensel deleted the fix/asset-update-race-condition branch March 5, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[API] tagAssets doesn't tag all assets randomly

4 participants