Как связать Long Poling обработчик и обычный http обработчик

Есть серверное приложение, главная проблема которого - обработка долгих (длинных) запросов. Время обработки файла для клиента может быть довольно большим (несколько минут) и это нормально для специфики сервиса. Но хостинг ограничивает время коннекта до 30 сек, после чего разрывает простаивающее (не было передачи ни одного байта с сервера) соединение. Его тоже можно понять.

Поэтому решил использовать Long Polling. Нашел для Go и используемого мной фреймворка (fiber) готовую библиотеку: https://github.com/LdDl/fiber-long-poll Но из примеров совершенно не смог понять как соединить этот вариант обработки запросов с моими обработчиками маршрутов. То есть на маршрут:

fileAPI.Post(`/to/text/longpoll`,t.LongPollFileHandler())

вырисовывается что-то подобное

func (t *Translator) LongPollFileHandler(manager *lp.LongpollManager) func(ctx *fiber.Ctx) 
     
    return func(c *fiber.Ctx) error {
        t.FileHandler(c)  // это мой стандартный обработчик
        ....
        return manager.SubscriptionHandler(c)
    } 
}

Но что при этом нужно менять в моем обработчике, переписывать ли его заново и как-то подстраивать - непонятно.

В конечно итоге хочется получить такой вариант: клиент делает запрос, отправляет файл и в цикле while получает ответы от сервера о промежуточных этапах обработки файла (json в котором указывается какая часть файла обработана и сколько всего частей - при выводе в html можно для прогресс-бара эту информацию использовать). Как только файл обработан - присылается финальное сообщение, в котором будет динамический url по которому данный файл клиент сможет скачать. Клиент завершает цикл и следующим запросом скачивает готовый файл, который на сервере будет какое-то время храниться или в ОЗУ или на диске (не суть). В общем, ничего особенного - такой подход используется на многих аналогичных сайтах.

Да, понимаю, что четкого вопроса нет - поэтому любые советы, ссылки на примеры с применением подобных подходов на Go, дополнительные примеры Long Polling с данной библиотекой и т.д. могут мне помочь.


func (t *Translator) FileHandler(c *fiber.Ctx) error {

    .... 
/*тут много кода для предварительной обработки файла и отправки его промежуточному ПО, 
дальше здесь все таски после обработки окажутся в структуре MainTask, которая везде передается по указателю 
*/    
    // читаем из канала куда пишутся все таски
    YAPI = t.WaitAll(ctx, main)
    if YAPI.Err != nil {
        cancel()
        httpCode := YAPI.Code
        if httpCode == 0 {
            httpCode = http.StatusInternalServerError
        }
        resp := &ClientResponse{Status: httpCode, Error: YAPI.Err}
        return t.SendJson(c, resp)

    } else {
        t.Log.Infof("[WAIT ALL ][%d] ALL DONE!", main.TaskCount)
        main.As = as

        switch do {
        case "docx":
            result = t.ReplyDocx(c, main)

        case "text":
            result = t.ReplyText(c, main)

        case "html":
            result = t.ReplyHtml(c, main)

        case "samehtml":
            result = t.ReplySameHtml(c, main)
        
        default:
            result = t.ReplyHtml(c, main)
        }
    }
    // чистим за unioffice в TEMP
    if main.Doc != nil {
        if main.Doc.TmpPath != "" {
            tmpPath := main.Doc.TmpPath
            go utils.CleanTmp(tmpPath)
        }
    }

    return result
}

Ответы (0 шт):