Я пытаюсь использовать gin для обработки HTTP-запросов, у меня есть обработчик, который принимает запрос, например
r.DELETE("/workspaces/:id", DoSomething)
Delete - это функция, работа которой заключается в том, чтобы вызвать действие "Destroy", которое может занять некоторое время. а затем выполните действие «Удалить».
Я также не хочу, чтобы пользовательский интерфейс блокировался, поэтому я хочу, чтобы объединение действий «Уничтожить» и «Удалить» выполнялось в асинхронном режиме.
Это моя реализация DoSomething.
func DoSomething(C *gin.Context){
CallDestroy(c)
go func(c){
timeout := time.After(30 * time.Minute)
ticker := time.NewTicker(10 * time.Second)
for {
select {
// Got a timeout! fail with a timeout error
case <-timeout:
return
// Got a tick, we should check on doSomething()
case <-ticker.C:
status := PoolForCompletion(c)
if status.Status == "FAILED" {
logger.Error("Detroy activity failed")
return
} else {
status := Delete(c)
return
}
}
}
}(c)
}
Для операции «Удалить» нужен идентификатор, который я извлекаю в реализации Удалить из params.
c.params("id")
fmt.Println(c.params("id")
Проблема, с которой я сталкиваюсь, заключается в смешении идентификаторов в рабочей области удаления.
Таким образом, теоретически для каждого вызова DoSomething удаление будет запускаться с уникальным идентификатором. Предположим, я делаю последовательные вызовы с параметрами 1,2,3. Так что в логах я должен увидеть 1,2,3.
Но то, что я вижу, это 1,3,3 или 1,2,2.
Я изучил контекстную документацию и узнал, что я использую указатель gin.context. Поэтому я также попытался использовать
C.Copy()
func DoSomething(C *gin.Context){
CallDestroy(c.Copy())
go func(c){
timeout := time.After(30 * time.Minute)
ticker := time.NewTicker(10 * time.Second)
for {
select {
// Got a timeout! fail with a timeout error
case <-timeout:
return
// Got a tick, we should check on doSomething()
case <-ticker.C:
status := PoolForCompletion(c.Copy())
if status.Status == "FAILED" {
logger.Error("Detroy activity failed")
return
} else {
status := Delete(c.Copy())
return
}
}
}
}(c.Copy())
}
Для создания копии контекста. Тем не менее, я получаю такое же поведение. Насколько я понимаю, контекст будет изолирован для всех запросов и не изменится в процедурах, даже если я не использую копию.