dependencies added
Some checks failed
Cross Compile Go / build (push) Has been cancelled

This commit is contained in:
ilbinek
2026-07-09 14:41:50 +02:00
parent 0b3464c563
commit 0d07148db6
7 changed files with 241 additions and 36 deletions

View File

@@ -26,34 +26,20 @@ func GetNextToBeIndexed(c *gin.Context) {
}
}
var addon models.Addon
ret := initializers.DB.Where("to_be_indexed = ?", true).Where("is_being_indexed = ?", false).Where("priority_indexing = ?", true).Where("blocked = ?", false).Where("current_version_size <= ?", maxSize).Order("updated_at asc").First(&addon)
if ret.Error == nil {
addon.IsBeingIndexed = true
addon.IndexStartTime = time.Now()
initializers.DB.Save(&addon)
c.JSON(200, gin.H{"guid": addon.ID, "currentVersion": addon.CurrentVersionNumber})
addon, err := claimNextAddon(maxSize, true)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
if ret.Error != nil && ret.Error != gorm.ErrRecordNotFound {
c.JSON(500, gin.H{"error": ret.Error.Error()})
return
if addon == nil {
addon, err = claimNextAddon(maxSize, false)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
}
ret = initializers.DB.Where("to_be_indexed = ?", true).Where("is_being_indexed = ?", false).Where("blocked = ?", false).Where("current_version_size <= ?", maxSize).Order("updated_at asc").First(&addon)
if ret.Error != nil && ret.Error != gorm.ErrRecordNotFound {
c.JSON(500, gin.H{"error": ret.Error.Error()})
return
}
if ret.Error == nil {
addon.IsBeingIndexed = true
addon.IndexStartTime = time.Now()
initializers.DB.Save(&addon)
if addon != nil {
c.JSON(200, gin.H{"guid": addon.ID, "currentVersion": addon.CurrentVersionNumber})
return
}
@@ -62,6 +48,44 @@ func GetNextToBeIndexed(c *gin.Context) {
c.JSON(200, gin.H{"guid": "", "currentVersion": ""})
}
// claimNextAddon picks the oldest indexable addon and claims it with an
// optimistic UPDATE, so concurrent indexers can never claim the same job.
// Returns nil when no candidate is available.
func claimNextAddon(maxSize int, priorityOnly bool) (*models.Addon, error) {
for range 5 {
query := initializers.DB.Where("to_be_indexed = ?", true).Where("is_being_indexed = ?", false).Where("blocked = ?", false).Where("current_version_size <= ?", maxSize)
if priorityOnly {
query = query.Where("priority_indexing = ?", true)
}
var addon models.Addon
ret := query.Order("updated_at asc").First(&addon)
if ret.Error == gorm.ErrRecordNotFound {
return nil, nil
}
if ret.Error != nil {
return nil, ret.Error
}
claim := initializers.DB.Model(&models.Addon{}).
Where("id = ?", addon.ID).
Where("is_being_indexed = ?", false).
Where("to_be_indexed = ?", true).
Updates(map[string]any{
"is_being_indexed": true,
"index_start_time": time.Now(),
})
if claim.Error != nil {
return nil, claim.Error
}
if claim.RowsAffected == 1 {
return &addon, nil
}
// lost the race to another indexer - retry with the next candidate
}
return nil, nil
}
func SaveIndexingResult(c *gin.Context) {
var result struct {
GUID string `json:"guid"`
@@ -185,6 +209,14 @@ func DeleteAddon(c *gin.Context) {
return
}
// Delete outgoing dependency edges; incoming edges stay - other addons
// still declare this dependency even if the addon row is gone
ret = initializers.DB.Where("addon_id = ?", addon.ID).Delete(&models.AddonDependency{})
if ret.Error != nil {
c.JSON(500, gin.H{"error": ret.Error.Error()})
return
}
// Delete the addon
ret = initializers.DB.Delete(&addon)
if ret.Error != nil {
@@ -196,15 +228,10 @@ func DeleteAddon(c *gin.Context) {
}
func checkIndexingTimeout() {
var addons []models.Addon
initializers.DB.Where("is_being_indexed = ?", true).Find(&addons)
for _, addon := range addons {
if time.Since(addon.IndexStartTime) > 30*time.Minute {
addon.IsBeingIndexed = false
initializers.DB.Save(&addon)
}
}
initializers.DB.Model(&models.Addon{}).
Where("is_being_indexed = ?", true).
Where("index_start_time < ?", time.Now().Add(-30*time.Minute)).
Update("is_being_indexed", false)
}
func SendCustomWebhook(webhookURL string, hook models.CustomHook) error {