简体   繁体   English

在Rest API中使用Goroutine-获取未定义的错误

[英]Working with goroutine in a rest api - getting undefined error

I am learning GO and wanted to make a simple rest API. 我正在学习GO,并想制作一个简单的Rest API。

What I want to do is fire off a goroutine after handling the api request and do the work asynchronously in the background. 我想做的是在处理api请求后触发goroutine,并在后台异步执行工作。

Here's my implementation so far: 到目前为止,这是我的实现:

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()
    }
}

When I try to run this code, I am getting the following error (on this line queue <- func() { ... } ): 当我尝试运行此代码时,出现以下错误(在此行queue <- func() { ... } ):

./main.go:46:2: undefined: queue ./main.go:46:2:未定义:队列

How can I make the queue channel available to my request handler (ie httprouter GET request handler func)? 如何使queue通道可用于我的请求处理程序(即httprouter GET请求处理程序func)?

Secondly, I cannot see the output from my log.Printf() calls in the console output (stdout), eg server status message when the app runs. 其次,我在控制台输出(stdout) log.Printf()调用的输出,例如,应用运行时的服务器状态消息。 Any ideas why? 有什么想法吗?

Couple of things are wrong, first your main function is not ordered correctly, you want to initialize you channel and start workers before you run err := http.ListenAndServe(apiServerPort, r) so something like this 几件事情是错误的,首先是您的主要功能未正确排序,您想在运行err := http.ListenAndServe(apiServerPort, r)之前初始化通道并启动工作程序err := http.ListenAndServe(apiServerPort, r)所以类似这样

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...
}

Then queue variable is not defined in the test() function, which is why you are getting ./main.go:46:2: undefined: queue . 然后在test()函数中未定义queue变量,这就是为什么要获取./main.go:46:2: undefined: queue原因。 You could fix it with a higher order function eg 您可以使用更高阶的函数来修复它,例如

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")
        }
    }
}

and then just bind it to the route with r.GET("/test", test(queue)) 然后使用r.GET("/test", test(queue))将其绑定到路由

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM