go - 在 rest api 中使用 goroutine - 出现未定义的错误

标签 go goroutine httprouter

我正在学习 GO,想做一个简单的 rest API。

我想做的是在处理完 api 请求后触发一个 goroutine,并在后台异步完成工作。

到目前为止,这是我的实现:

package main

import (
    "encoding/json"
    "log"
    "net/http"

    "github.com/julienschmidt/httprouter"
)

// APIResponse represents common structure of every api call response
type APIResponse struct {
    Status string `json:"status"`
    Error  string `json:"error,omitempty"`
    Data   string `json:"data,omitempty"`
}

// Action represents what could be passed to the goroutine
type Action = func()

// ActionQueue represents a buffered channel
type ActionQueue = chan Action

func main() {
    r := httprouter.New()
    r.GET("/test", test)

    var apiServerPort = ":80"
    err := http.ListenAndServe(apiServerPort, r)
    if err != nil {
        log.Fatal("ListenAndServe:", err)
    } else {
        log.Printf("Started server on port %s", apiServerPort)
    }

    var queueSize = 10
    queue := make(ActionQueue, queueSize)
    for i := 0; i < queueSize; i++ {
        go worker(queue)
    }
    log.Printf("Started %d queue workers", queueSize)
}

func test(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
    successResponse(w, http.StatusOK, "Hello World")
    queue <- func() {
        log.Println("Hello from queue worker, initiated by api call")
    }
}

func successResponse(w http.ResponseWriter, statusCode int, successData string) {
    sendResponse(w, statusCode, "", successData)
}

func errorResponse(w http.ResponseWriter, statusCode int, errorData string) {
    sendResponse(w, statusCode, errorData, "")
}

func sendResponse(w http.ResponseWriter, statusCode int, errorData string, responseData string) {
    w.WriteHeader(statusCode)
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(&APIResponse{Status: http.StatusText(statusCode), Error: errorData, Data: responseData})
}

func worker(queue ActionQueue) {
    for action := range queue {
        action()
    }
}

当我尝试运行此代码时,出现以下错误(在 queue <- func() { ... } 这一行):

./main.go:46:2: undefined: queue

如何制作 queue我的请求处理程序可用的 channel (即 httprouter GET 请求处理程序函数)?

其次,我看不到 log.Printf() 的输出在控制台输出 (stdout) 中调用,例如应用程序运行时的服务器状态消息。有什么想法吗?

最佳答案

有几件事是错误的,首先你的 main 函数没有正确排序,你想在运行 err := http.ListenAndServe(apiServerPort, r) 之前初始化你的 channel 并启动 worker 等等像这样

func main() {
    var queueSize = 10
    queue := make(ActionQueue, queueSize)
    for i := 0; i < queueSize; i++ {
        go worker(queue)
    }
    log.Printf("Started %d queue workers", queueSize)

    // routers and stuff...
}

queue 变量未在 test() 函数中定义,这就是为什么您得到 ./main.go:46:2: undefined : 队列。您可以使用高阶函数修复它,例如

func test(queue ActionQueue) httprouter.Handle {
    return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
        successResponse(w, http.StatusOK, "Hello World")
        queue <- func() {
            log.Println("Hello from queue worker, initiated by api call")
        }
    }
}

然后用 r.GET("/test", test(queue))

将它绑定(bind)到路由

关于go - 在 rest api 中使用 goroutine - 出现未定义的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51528137/

相关文章:

go - 死锁在goroutines中

http - 将 URL 路径与页面名称与 Go 中的 URL 路由匹配的正确方法?

go - 在 Go HTTP 处理程序中使用未导出的结构键获取上下文值时为 nil

Golang时间戳解析

go - go routines 怎么可能完美交错呢?

go - 我在并发方面缺少什么?

go - 如何在GoLang中解析url中的多个参数?

xml - 具有命名空间的 Golang XML Marshal

amazon-web-services - AWS CloudTrail Create API for Go SDK 抛出错误消息 "InsufficientS3BucketPolicyException: Incorrect S3 bucket policy is detected for bucket: "

database - KyotoCabinet (TreeDB) 性能严重下降