Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang, unable to have value pushed into 'global' channel when handling HTTP requests

Tags:

go

channel

Currently I am working on an application that can take anywhere from a few seconds to 1 hour + to process. Because of this using a channel to block requests while others are processing seems like a good fit. The following is an example of what Im trying to accomplish, however I am having an issue as it seems like my program is stalling when trying to add data into said channel (see below).

package main

import (
    "net/http"

    "github.com/gorilla/mux"
)

type Request struct {
    Id string
}

func ConstructRequest(id string) Request {
    return Request{Id: id}
}

var requestChannel chan Request // <- Create var for channel

func init() {
    r := mux.NewRouter()
    r.HandleFunc("/request/{id:[0-9]+}", ProcessRequest).Methods("GET")
    http.Handle("/", r)
}

func main() {
    // start server
    http.ListenAndServe(":4000", nil)

    requestChannel = make(chan Request) // <- Make channel and assign to var

    go func() {
        for {
            request, ok := <-requestChannel

            if !ok{
                return
            }

            fmt.Println(request.Id)
        }
    }()

}

func ProcessRequest(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)

    newRequest := api.ConstructRequest(params["id"])

    requestChannel <- newRequest // <- it is stopping here, not adding the value to the channel

    w.Write([]byte("Received request"))
}
like image 835
user2737876 Avatar asked Apr 14 '15 21:04

user2737876


1 Answers

Your channel is not initialised and, per specification, send on a nil channel blocks forever. This is because http.ListenAndServe is a blocking operation, so neither requestChannel = make(chan Request) nor your go func() is being called.

Moving http.ListenAndServe to the end of the main block should fix the problem.

like image 130
tomasz Avatar answered Oct 31 '22 13:10

tomasz