超时是否会导致API端点多次触发



我有一个GO Post API端点,处理程序中有一个有些耗时的任务(即使在本地运行时,时间也可能是2分钟(。

在我的FE中,我调用API一次,它只触发一次(在网络选项卡中,没有多个请求((1(。API调用的运行时间不同,因为它是根据一些动态数据运行的。但在API方面,调用需要一些时间并成功,但不会发送响应(在FE方面仍然挂起(。然后处理程序立即再次运行(在FE端仍然Pending(,逻辑再次运行。因此,由于逻辑原因,由于它已经运行,所以它失败了。然后,该响应将作为对FE请求的响应返回(1(。因此,逻辑是成功的,DB被更新,但响应发送了一个错误。

这是由于超时问题吗?如果是,我该如何修复?

我使用围棋作为go框架,并为FE做出反应。

r := chi.NewRouter()
r = helpers.AttachLoggerMiddleware(r, pretty)
r.Route("/apps", func(r chi.Router) {
r.Post("/{id}/clone", service.Clone)
}

func (s *Service) Clone(w http.ResponseWriter, r *http.Request) {     
fmt.Println("Calling Clone !!")
//logic
}

这是API方法如何配置的一个示例

您应该重新设计使用Long轮询机制的方法,使用WebSosket或JSON流也将是一种选择。

一点解释:

你有一项耗时的任务(需要2分钟,如果你的应用程序负载更大,肯定会花更多的时间(。因此,如果您将使用一个简单的请求-响应方法,则会因为超时问题而出现错误。

正因为如此,使用所提出的方法将更适合您的情况。

让我们看看WebSocket示例:

在你的go代码中,你会有这样的东西(这只是一个跟上想法的例子,我不知道chi,并使用github.com/gorilla/websocket和香草net/http,但我很确定你也可以使用chi(:

package main
import (
"fmt"
"github.com/gorilla/websocket"
"log"
"net/http"
"time"
)
var upgrader = websocket.Upgrader{
ReadBufferSize:  1024,
WriteBufferSize: 1024,
}
func main() {
http.HandleFunc("/ws", wsHandler)

panic(http.ListenAndServe(":8080", nil))
}
func wsHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}

if err != nil {
http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
}

go echo(conn)
}
func echo(conn *websocket.Conn) {
defer conn.Close()
m := ""

err := conn.ReadJSON(&m)
if err != nil {
fmt.Println("Error reading json", err)
}

// receive some data from your reactjs
fmt.Printf("Got message: %#vn", m)

om := struct {
mes string
}{
mes: "Send to client",
}

// send some data
if err = conn.WriteJSON(om); err != nil {
fmt.Println(err)
}

// do some work in 2 min
time.Sleep(120 * time.Second)

// send some data
if err = conn.WriteJSON(om); err != nil {
fmt.Println(err)
}
}

在你的react js应用程序中,你会有这样的东西:

import React, { useState } from "react";
function  App() {
let isDone = false;
const messages = []
const ws = new WebSocket("wss://localhost:8080/ws");
const apiCall = {
mes: "Your json for server" 
};
ws.onopen = (event) => {
ws.send(JSON.stringify(apiCall));
};
ws.onmessage = function (event) {
const json = JSON.parse(event.data);
messages.push(json)
} catch (err) {
console.log(err);
}
};

ws.onclose = function (event) {
isDone = true
};

const mess = messages.map((item) => {
return (
<div>
<p> {item}</p>
</div>
);
});
return (
<div>
<div>{mess}</div>
<div> is work done?: {isDone}</div> 
</div> 
);
}
export default  App;

在本例中,我们向服务器发送一些信息,并开始等待工作何时完成(ws关闭时为isDone = true(,同时接收一些消息(在您的情况下可能不需要(。

使用Long轮询和JSON流实现这个想法也是如此(我认为你很容易在互联网上找到一些东西:(

最新更新