fix mutli dowload
This commit is contained in:
parent
d0eebe3ffc
commit
b52729630a
@ -25,7 +25,27 @@ var seriesRegex = regexp.MustCompile(`^(.+?)\.S\d{2}E\d{2}`)
|
||||
var (
|
||||
jobs = make(map[string]*runner.DownloadJob)
|
||||
jobsMu sync.Mutex
|
||||
// --- Ajouts ---
|
||||
inFlightMu sync.Mutex
|
||||
inFlight = map[string]struct{}{} // set des jobs déjà en cours (par id)
|
||||
|
||||
parallelism = 4 // <— ajuste le nombre de DL en parallèle
|
||||
sem = make(chan struct{}, parallelism)
|
||||
)
|
||||
func tryMarkInFlight(id string) bool {
|
||||
inFlightMu.Lock()
|
||||
defer inFlightMu.Unlock()
|
||||
if _, ok := inFlight[id]; ok {
|
||||
return false
|
||||
}
|
||||
inFlight[id] = struct{}{}
|
||||
return true
|
||||
}
|
||||
func unmarkInFlight(id string) {
|
||||
inFlightMu.Lock()
|
||||
delete(inFlight, id)
|
||||
inFlightMu.Unlock()
|
||||
}
|
||||
func HandleAddJobsMultiple(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// 1. Parsing des champs du formulaire
|
||||
@ -167,43 +187,62 @@ func HandleAddJobsMultiple(db *gorm.DB) gin.HandlerFunc {
|
||||
|
||||
|
||||
func HandleStartJob(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
log.Printf("[StartJob] ID = %s", id)
|
||||
return func(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
log.Printf("[StartJob] ID = %s", id)
|
||||
|
||||
// 1. Vérifie si le job est déjà en mémoire
|
||||
jobsMu.Lock()
|
||||
job, exists := jobs[id]
|
||||
jobsMu.Unlock()
|
||||
// Empêche un job déjà en cours d'être relancé
|
||||
if !tryMarkInFlight(id) {
|
||||
log.Printf("[StartJob] Job %s déjà en cours, on ignore", id)
|
||||
c.Status(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
// 2. Sinon, récupère depuis la BDD
|
||||
if !exists {
|
||||
var j runner.DownloadJob
|
||||
if err := db.First(&j, "id = ?", id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Job introuvable"})
|
||||
return
|
||||
}
|
||||
jobCopy := j
|
||||
jobsMu.Lock()
|
||||
jobs[id] = &jobCopy
|
||||
job = &jobCopy
|
||||
jobsMu.Unlock()
|
||||
}
|
||||
// Récupération du job depuis la mémoire ou la DB
|
||||
jobsMu.Lock()
|
||||
job, exists := jobs[id]
|
||||
jobsMu.Unlock()
|
||||
if !exists {
|
||||
var j runner.DownloadJob
|
||||
if err := db.First(&j, "id = ?", id).Error; err != nil {
|
||||
unmarkInFlight(id)
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Job introuvable"})
|
||||
return
|
||||
}
|
||||
jobCopy := j
|
||||
jobsMu.Lock()
|
||||
jobs[id] = &jobCopy
|
||||
job = &jobCopy
|
||||
jobsMu.Unlock()
|
||||
}
|
||||
|
||||
clt:= client.NewClient(db)
|
||||
account := runner.GetFirstActiveAccount(clt)
|
||||
if account == nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Aucun compte Debrid-Link actif"})
|
||||
return
|
||||
}
|
||||
clt.SetAccount(account)
|
||||
// Init client Debrid-Link
|
||||
clt := client.NewClient(db)
|
||||
account := runner.GetFirstActiveAccount(clt)
|
||||
if account == nil {
|
||||
unmarkInFlight(id)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Aucun compte Debrid-Link actif"})
|
||||
return
|
||||
}
|
||||
clt.SetAccount(account)
|
||||
|
||||
go runner.StartDownload(job, job.Link, clt, db)
|
||||
runner.Broadcast()
|
||||
// Lancement asynchrone avec limite de parallélisme
|
||||
go func(job *runner.DownloadJob) {
|
||||
sem <- struct{}{} // bloque si trop de jobs en cours
|
||||
defer func() {
|
||||
<-sem
|
||||
unmarkInFlight(job.ID)
|
||||
runner.Broadcast()
|
||||
}()
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
runner.StartDownload(job, job.Link, clt, db)
|
||||
}(job)
|
||||
|
||||
runner.Broadcast()
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
func HandlePauseJob() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
@ -214,39 +253,60 @@ func HandlePauseJob() gin.HandlerFunc {
|
||||
}
|
||||
}
|
||||
func HandleResumeJob(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
return func(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
log.Printf("[ResumeJob] ID = %s", id)
|
||||
|
||||
jobsMu.Lock()
|
||||
job, exists := jobs[id]
|
||||
jobsMu.Unlock()
|
||||
// Empêche un job déjà en cours d'être relancé
|
||||
if !tryMarkInFlight(id) {
|
||||
log.Printf("[ResumeJob] Job %s déjà en cours, on ignore", id)
|
||||
c.Status(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
if !exists {
|
||||
var j runner.DownloadJob
|
||||
if err := db.First(&j, "id = ?", id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Job introuvable"})
|
||||
return
|
||||
}
|
||||
jobCopy := j
|
||||
jobsMu.Lock()
|
||||
jobs[id] = &jobCopy
|
||||
job = &jobCopy
|
||||
jobsMu.Unlock()
|
||||
}
|
||||
// Récupération du job depuis la mémoire ou la DB
|
||||
jobsMu.Lock()
|
||||
job, exists := jobs[id]
|
||||
jobsMu.Unlock()
|
||||
if !exists {
|
||||
var j runner.DownloadJob
|
||||
if err := db.First(&j, "id = ?", id).Error; err != nil {
|
||||
unmarkInFlight(id)
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Job introuvable"})
|
||||
return
|
||||
}
|
||||
jobCopy := j
|
||||
jobsMu.Lock()
|
||||
jobs[id] = &jobCopy
|
||||
job = &jobCopy
|
||||
jobsMu.Unlock()
|
||||
}
|
||||
|
||||
clt := client.NewClient(db)
|
||||
account := runner.GetFirstActiveAccount(clt)
|
||||
if account == nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Aucun compte actif"})
|
||||
return
|
||||
}
|
||||
clt.SetAccount(account)
|
||||
// Init client Debrid-Link
|
||||
clt := client.NewClient(db)
|
||||
account := runner.GetFirstActiveAccount(clt)
|
||||
if account == nil {
|
||||
unmarkInFlight(id)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Aucun compte Debrid-Link actif"})
|
||||
return
|
||||
}
|
||||
clt.SetAccount(account)
|
||||
|
||||
go runner.StartDownload(job, job.Link, clt, db)
|
||||
runner.Broadcast()
|
||||
// Reprise asynchrone avec limite de parallélisme
|
||||
go func(job *runner.DownloadJob) {
|
||||
sem <- struct{}{} // bloque si trop de jobs en cours
|
||||
defer func() {
|
||||
<-sem
|
||||
unmarkInFlight(job.ID)
|
||||
runner.Broadcast()
|
||||
}()
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
runner.StartDownload(job, job.Link, clt, db)
|
||||
}(job)
|
||||
|
||||
runner.Broadcast()
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
func HandleDeleteJob(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user