如何使我的函数立即返回Slack?

时间:2019-02-20 16:48:10

标签: go slack slack-api

我正在尝试为Slack开发一个简单的API,我想立即向用户返回一些信息,以避免3000毫秒的超时。

这是我的问题:

  1. 为什么This should be printed to Slack first不能立即打印,而我只得到了最后一条消息,即The long and blocking process completed?但是它会出现在ngrok日志中。

  2. 即使我已经在使用go例程,为什么我的函数仍然达到3000毫秒的限制?是因为done频道吗?

func testFunc(w http.ResponseWriter, r *http.Request) {
    // Return to the user ASAP to avoid 3000ms timeout.
    // But this doesn't work. Nothing is returned but
    // the message appeared in ngrok log.
    fmt.Fprintln(w, "This should be printed to Slack first!")

    // Get the response URL.
    r.ParseForm()
    responseURL := r.FormValue("response_url")

    done := make(chan bool)

    go func() {
        fmt.Println("Warning! This is a long and blocking process.")
        time.Sleep(5 * time.Second)

        done <- true
    }()

    // This works! I received this message. But I still reached the 3000ms timeout.
    func(d bool) {
        if d == true {
            payload := map[string]string{"text": "The long and blocking process completed!"}
            j, err := json.Marshal(payload)

            if err != nil {
                w.WriteHeader(http.StatusInternalServerError)
            }

            http.Post(responseURL, "application/json", bytes.NewBuffer(j))
        }
    }(<-done)
}

2 个答案:

答案 0 :(得分:2)

http.ResponseWriter流默认情况下被缓冲。如果您想将数据实时发送到客户端(例如HTTP SSE),则需要在每个“事件”之后刷新流:

wf, ok := w.(http.Flusher)

if !ok {
    http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
    return
}

fmt.Fprintln(w, "This should be printed to Slack first!")

wf.Flush()

冲洗很昂贵-因此请利用go的缓冲功能。一旦您的处理程序最终退出,总会有一个隐式刷新(因此,为什么您看到输出为“晚期”)。

答案 1 :(得分:1)

我正在学习golang阶段。这是我的理解: 1.通道的任何操作都被阻止 2.您正在

中的频道上书写
    go func() {
        fmt.Println("Warning! This is a long and blocking process.")
        time.Sleep(5 * time.Second)

        done <- true
    }()
  1. 调度程序仍在移至主要功能中,并尝试从通道读取数据,但它正在等待查看通道上是否写入了某些内容。因此,它被阻塞了,当以上功能通过在通道上写入完成时,控件又回来了,并且主程序再次开始执行。

注意:专家们将能够更好地进行解释。