Use tmp storage while uploading, use tx where needed

Use temporary storage while the client is streaming the file to GARM.
This ensures that while uploading, we don't lock the blob database. On slow
connections this would mean that no readers would be able to access the db
while data was being written to it via the upload process.

By saving the file to a temporary location and only after we receive the
entire thing, add it to the DB, we significantly reduce the time we need to
keep the DB locked.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2025-10-08 19:03:18 +00:00 committed by Gabriel
parent db2b908605
commit 73b330467b
8 changed files with 193 additions and 64 deletions

View file

@ -473,6 +473,22 @@ type FileObject struct {
SHA256 string `gorm:"type:text"`
// Tags is a JSON array of tags
TagsList []FileObjectTag `gorm:"foreignKey:FileObjectID;constraint:OnDelete:CASCADE"`
// Content is a foreign key to a different table where the blob is actually stored.
// Updating a field in an sqlite 3 DB will read the entire field, update the column
// and write it back to a different location. SQLite3 will then mark the old row as "deleted"
// and allow it to be vaccumed. But if we have a blob column with a huge blob, any
// update operation will consume a lot of resources and take a long time.
// Using a dedicated table for the blob (which doesn't change), speeds up updates of
// metadata fields like name, description, tags, etc.
Content FileBlob `gorm:"foreignKey:FileObjectID;constraint:OnDelete:CASCADE"`
}
// FileBlob is the immutable blob of bytes that once written will not be changed.
// We leave the SHA256, file type and size in the parent table, because we need to
// we able to get that info easily, without preloading the blob table.
type FileBlob struct {
gorm.Model
FileObjectID uint `gorm:"index:idx_fileobject_blob_id"`
// Content is a BLOB column for storing binary data
Content []byte `gorm:"type:blob"`
}