请使用golang beego 解释并优化下面代码实现将模型数据的关闭更加灵活可在删除模型函数中实现删除函数并且通过token同时中断和停止数据发放和驱动:var driverMutex syncMutex token2driver = makemapstringchan- intfunc HandelModelDataframes int32 coefl float32 token stri
下面是使用golang beego优化的代码:
var (
driverMutex sync.Mutex
token2driver = make(map[string]chan struct{})
)
func HandelModelData(frames [][]int32, coefl float32, token string, commonInfo string, seq int) {
sig := getOrCreateDriver(token)
defer closeDriver(token, sig, commonInfo)
streamInfoRes, err := getStreamInfo(token, commonInfo)
if err != nil {
logs.Error("%s, err = %v", commonInfo, err)
return
}
socket, err := getUDPSocket(streamInfoRes.Data.Ip, 11111)
if err != nil {
logs.Error("%s, ip = %s, port = %d, err = %v", commonInfo, streamInfoRes.Data.Ip, 11111, err)
return
}
defer socket.Close()
err = StartBSDriver(token, seq)
if err != nil {
logs.Error("%s, StartBSDriver failed, err = %v", commonInfo, err)
return
}
for _, frame := range frames {
select {
case <-sig:
logs.Info("%s, recv quit sig, quit now", commonInfo)
return
default:
framef := make([]float32, 61)
for j := 0; j < 51; j++ {
framef[j] = float32(frame[j]) / coefl
}
data := MakeBSFrame(framef)
err := sendData(socket, data)
if err != nil {
logs.Error("%s, sendData failed, err = %v", commonInfo, err)
return
}
time.Sleep(15 * time.Millisecond)
}
}
err = StopBSDriver(token, seq)
if err != nil {
logs.Error("%s, StopBSDriver failed, err = %v", commonInfo, err)
return
}
logs.Info("%s, finish", commonInfo)
}
func getOrCreateDriver(token string) chan struct{} {
driverMutex.Lock()
defer driverMutex.Unlock()
sig, ok := token2driver[token]
if !ok {
sig = make(chan struct{})
token2driver[token] = sig
} else {
logs.Info("%s, emmit sig flag, to quit last request", commonInfo)
close(sig) // 关闭上一个请求的关闭通道
}
return sig
}
func closeDriver(token string, sig chan struct{}, commonInfo string) {
driverMutex.Lock()
defer driverMutex.Unlock()
_, ok := token2driver[token]
if ok {
delete(token2driver, token)
}
logs.Info("%s, finish", commonInfo)
}
func getStreamInfo(token string, commonInfo string) (*protocol.StreamInfoRes, error) {
api := appconf.StreamInfoApi + "?token=" + token
resp, err := http.Get(api)
if err != nil {
logs.Error("%s, api = %v, err = %v", commonInfo, api, err)
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
logs.Error("%s, api = %v, status = %d", commonInfo, api, resp.StatusCode)
return nil, errors.New("Invalid status code")
}
var streamInfoRes protocol.StreamInfoRes
err = json.NewDecoder(resp.Body).Decode(&streamInfoRes)
if err != nil {
logs.Error("%s, err = %v", commonInfo, err)
return nil, err
}
if streamInfoRes.Code != 200 {
logs.Error("%s HandelModelData, err = %v", commonInfo, streamInfoRes)
return nil, errors.New("Invalid response code")
}
return &streamInfoRes, nil
}
优化说明:
- 将
token2driver的值的类型从chan<- int改为chan struct{},这样可以避免在通道中发送不必要的数据。 - 将
sig的类型从chan int改为chan struct{},这样可以避免在通道中发送不必要的数据。 - 删除了
closeDriver函数中的关闭通道操作,因为关闭通道的操作已经在getOrCreateDriver函数中完成了。 - 在
getOrCreateDriver函数中,关闭前一个请求的关闭通道。 - 使用
chan struct{}代替chan int,因为在该代码中并不需要在通道中发送具体的值,只需要通过关闭通道来通知退出即可
原文地址: https://www.cveoy.top/t/topic/h96O 著作权归作者所有。请勿转载和采集!