在循环中执行goroutine并将值传递给另一个包中的变量

时间:2018-12-23 01:16:35

标签: go goroutine

我很难将变量从主程序包传递到另一个程序包。

我要做什么:

我有一个简单的http守护程序,该守护程序可以接收传入的POST请求,并将其推送到RabbitMQ实例,该消息将由某些工作程序处理。由于消息可能很大,因此我尝试实现一个简单的资源管理器。它应该接受或拒绝请求。

它是这样的:

package main

import (
    "flag"
    "fmt"
    "github.com/couchbaselabs/logg"
    "net/http"
    _ "net/http/pprof"
)

var resourceChannel = make(chan bool)
var ampqApiConfig = worker.DefaultResManagerConfig()
var ServiceCanAccept bool

func main() {
    var http_port int
    flagFunc := func() {
        flag.IntVar(
            &http_port,
            "http_port",
            8080,
            "The http port to listen on, eg, 8081",
        )
    }

    rabbitConfig := worker.DefaultConfigFlagsOverride(flagFunc)

    // any requests to root, just redirect to main page
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        text := `<h1>We are running!<h1>`
        fmt.Fprintf(w, text)
    })

    http.Handle("/req", worker.NewHttpHandler(rabbitConfig))
    http.Handle("/status", worker.NewHttpStatusHandler())
    listenAddr := fmt.Sprintf(":%d", http_port)

    logg.LogTo("HTTP", "Starting listener on %v", listenAddr)
    // start a goroutine which will decide if we have resources for future requests
    go func() {
        for {
            resourceChannel <- worker.AcceptRequest(&ampqApiConfig)
            ServiceCanAccept = <-resourceChannel
            worker.ServiceCanAccept = ServiceCanAccept
            time.Sleep(10 * time.Second)
        }
    }()
    logg.LogError(http.ListenAndServe(listenAddr, nil))
}

我在通道和全局变量上方定义。然后,我尝试每10秒运行一次布尔函数(AcceptRequest),并将变量传递给软件包“ worker”中的woker.ServiceCanAccept变量。但不幸的是,它不起作用。 goroutine仅执行一次(至少我只看到一次来自资源管理器的日志),并且目标包中worker.ServiceCanAccept的值不变。这是第一个问题。

对于每个请求,将调用http.Handle("/req", worker.NewHttpHandler(rabbitConfig)),并执行下面的ServeHTTP。但是var ServiceCanAccept bool永远不会改变。我是否需要创建一个与包main中相同名称的通道,并从中读取值?

package worker

import (
    "encoding/json"
    "fmt"
    "github.com/couchbaselabs/logg"
    "net/http"
)

type HttpHandler struct {
    RabbitConfig RabbitConfig
}

func NewHttpHandler(r RabbitConfig) *HttpHandler {
    return &HttpHandler{
        RabbitConfig: r,
    }
}

var ServiceCanAccept bool

func (s *HttpHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {

    logg.LogTo("HTTP", "serveHttp called")
    defer req.Body.Close()

    Request := Request{}
    decoder := json.NewDecoder(req.Body)
    err := decoder.Decode(&Request)
    if err != nil {
        logg.LogError(err)
        http.Error(w, "Unable to unmarshal json", 500)
        return
    }

    Result, err := HandleRequest(Request, s.RabbitConfig)

    if err != nil {
        msg := "Unable to perform decode.  Error: %v"
        errMsg := fmt.Sprintf(msg, err)
        logg.LogError(fmt.Errorf(errMsg))
        http.Error(w, errMsg, 500)
        return
    }
    w.Header().Set("Content-Type", "application/json")
    js, err := json.Marshal(Result)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    w.Write(js)

}

func HandleRequest(Request Request, rabbitConfig RabbitConfig) (Result, error) {

    defaultResManagerConfig := DefaultResManagerConfig()
    if !ServiceCanAccept {
        err := fmt.Errorf("no ressources available to proced the request")
        return Result{}, err
    }

    switch Request.InplaceDecode {
    case true:
        Engine := NewEngine(Request.EngineType)

        Result, err := Engine.ProcessRequest(Request)

        if err != nil {
            msg := "Error processing request.  Error: %v"
            errMsg := fmt.Sprintf(msg, err)
            logg.LogError(fmt.Errorf(errMsg))
            return Result{}, err
        }

        return Result, nil
    default:
        Client, err := NewRpcClient(rabbitConfig)
        if err != nil {
            logg.LogError(err)
            return Result{}, err
        }
        Result, err := Client.DecodeImage(Request)
        if err != nil {
            logg.LogError(err)
            return Result{}, err
        }
        return Result, nil
    }
}

谢谢!

0 个答案:

没有答案