Как отправлять обновления из давно запущенной программы? - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть программа для длительной работы.Когда работа завершена, результаты передаются на канал.Тем временем, пока задание выполняется, я хочу постоянно обновлять API со статусом RUNNING.

Пока у меня есть следующий код:

func getProgressTimeout() <-chan time.Time {
    return time.After(5 * time.Minute)
}

func runCommand(arg *Request) {
    chanResult := make(chan Results)

    go func(args *Request, c chan Results) {
        resp, err := execCommand(args)
        c <- Results{
            resp: resp,
            err:  err,
        }
    }(arg, chanResult)

    var err error

progressLoop:
    for {
        select {
        case <-getProgressTimeout():
            updateProgress()  // this method will send status= RUNNING to a REST API

        case out := <-chanResult:
            err = jobCompleted(request, out)
            break progressLoop
        }
    }
    return err
}

Я новичок вgolang.И я достиг вышеуказанного кода после множества проб и ошибок и поиска в Google.Теперь это работает.Тем не менее, мне не кажется интуитивным, когда я смотрю на это (это может быть очень хорошо, потому что я все еще пытаюсь освоить способ Го делать вещи).Итак, мой вопрос, могу ли я реорганизовать это в лучшую форму?Есть ли какая-то существующая модель, которая применима в этом сценарии?Или, если есть какой-то совершенно иной подход к продолжению отправки периодических обновлений во время выполнения задания?

Кроме того, любые предложения по улучшению моего параллелизма golang также приветствуются.:)

Заранее спасибо!

1 Ответ

0 голосов
/ 01 февраля 2019

Рассмотрите возможность использования time.NewTicker , который отправляет периодическое значение в канал.Вот пример из документации:

package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()
    done := make(chan bool)
    go func() {
        time.Sleep(10 * time.Second)
        done <- true
    }()
    for {
        select {
        case <-done:
            fmt.Println("Done!")
            return
        case t := <-ticker.C:
            fmt.Println("Current time: ", t)
        }
    }
}

Обратите внимание, что встроенная процедура, вызывающая func, эмулирует длинную задачу, спя в течение 10 секунд, в то время как вызывающая сторона использует select для ожидания результата, а такжеполучение периодических событий от тикера - здесь вы можете выполнить обновление прогресса API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...