This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user