如何让我的函数 return 立即进入 Slack?
How to make my function return to Slack right away?
我正在尝试为 Slack 开发一个简单的 API,我想 return 立即向用户提供一些东西以避免 3000 毫秒超时。
这是我的问题:
为什么 This should be printed to Slack first
没有立即打印出来,而是我只收到最后一条消息,即 The long and blocking process completed
?但是它出现在 ngrok 日志中。
为什么我的函数仍然达到 3000 毫秒限制,即使我已经在使用 go 例程?是因为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)
}
我正在学习golang阶段。这是我的理解:
1. 任何对通道的操作都是阻塞的
2. 您正在
中的频道上写作
go func() {
fmt.Println("Warning! This is a long and blocking process.")
time.Sleep(5 * time.Second)
done <- true
}()
- 调度程序仍在 main 函数中移动并尝试从通道中读取,但它正在等待查看是否有内容写入通道。所以它被阻塞了,当上面的函数通过在通道上写入完成时,控件返回并且 main 再次开始执行。
注:高手能解释的更好
http.ResponseWriter
流默认缓冲。如果你想将数据实时发送到客户端(例如 HTTP SSE),你需要在每个 'event':
之后刷新流
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 的缓冲。一旦您的处理程序最终退出,总会有一个隐式刷新(因此您看到输出的原因 'late')。
我正在尝试为 Slack 开发一个简单的 API,我想 return 立即向用户提供一些东西以避免 3000 毫秒超时。
这是我的问题:
为什么
This should be printed to Slack first
没有立即打印出来,而是我只收到最后一条消息,即The long and blocking process completed
?但是它出现在 ngrok 日志中。为什么我的函数仍然达到 3000 毫秒限制,即使我已经在使用 go 例程?是因为
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)
}
我正在学习golang阶段。这是我的理解: 1. 任何对通道的操作都是阻塞的 2. 您正在
中的频道上写作 go func() {
fmt.Println("Warning! This is a long and blocking process.")
time.Sleep(5 * time.Second)
done <- true
}()
- 调度程序仍在 main 函数中移动并尝试从通道中读取,但它正在等待查看是否有内容写入通道。所以它被阻塞了,当上面的函数通过在通道上写入完成时,控件返回并且 main 再次开始执行。
注:高手能解释的更好
http.ResponseWriter
流默认缓冲。如果你想将数据实时发送到客户端(例如 HTTP SSE),你需要在每个 'event':
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 的缓冲。一旦您的处理程序最终退出,总会有一个隐式刷新(因此您看到输出的原因 'late')。