3 回答

TA貢獻(xiàn)1878條經(jīng)驗(yàn) 獲得超4個(gè)贊
是的,如果我不阻止它,你的觀點(diǎn)“c) 是正確的” 。
為了保存響應(yīng)編寫器,您不應(yīng)該在其中調(diào)用 go routine。相反,您應(yīng)該將ServeHTTP作為 go-routine 調(diào)用,大多數(shù) http 服務(wù)器實(shí)現(xiàn)都這樣做。
這樣你就不會(huì)阻止任何 api 調(diào)用,每個(gè) api 調(diào)用將在不同的 go-routine 中運(yùn)行,被它們的功能阻止。
由于您的“jobs chan QueueElement”是單個(gè)通道(不是緩沖通道),因此您的所有進(jìn)程都在“gv.jobs <- newPrintJob”處被阻塞。
您應(yīng)該使用緩沖通道,以便所有 api 調(diào)用都可以將其添加到隊(duì)列中并根據(jù)工作完成或超時(shí)獲得響應(yīng)。
擁有緩沖通道也可以模擬打印機(jī)在現(xiàn)實(shí)世界中的內(nèi)存限制。(隊(duì)列長(zhǎng)度 1 是特例)

TA貢獻(xiàn)1817條經(jīng)驗(yàn) 獲得超6個(gè)贊
我已經(jīng)為您的代碼添加了一些更新?,F(xiàn)在它像你描述的那樣工作。
package main
import (
"database/sql"
"fmt"
"log"
"math/rand"
"net/http"
"sync"
"time"
)
type QueueElement struct {
jobid string
rw http.ResponseWriter
doneChan chan struct{}
}
type GlobalVars struct {
db *sql.DB
wg sync.WaitGroup
jobs chan QueueElement
}
func (gv *GlobalVars) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/StartJob":
fmt.Printf("incoming\r\n")
doneC := make(chan struct{}, 1) //Buffered channel in order not to block the worker routine
go func(doneChan chan struct{}, w http.ResponseWriter) {
gv.jobs <- QueueElement{
doneChan: doneC,
jobid: "jobid",
}
}(doneC, w)
select {
case <-time.Tick(time.Second * 5):
fmt.Fprintf(w, "job is taking more than 5 seconds to complete\r\n")
fmt.Printf("took longer than 5 secs\r\n")
case <-doneC:
fmt.Fprintf(w, "instant reply from serveHTTP\r\n")
fmt.Printf("instant\r\n")
}
default:
fmt.Fprintf(w, "No such Api")
}
}
func worker(jobs <-chan QueueElement) {
for {
job := <-jobs
fmt.Println("START /i /b try.cmd")
fmt.Printf("job done")
randTimeDuration := time.Second * time.Duration(rand.Intn(7))
time.Sleep(randTimeDuration)
// processExec("START /i /b processAndPrint.exe -" + job.jobid)
job.doneChan <- struct{}{}
}
}
func main() {
// create a GlobalVars instance
gv := GlobalVars{
//db: db,
jobs: make(chan QueueElement),
}
go worker(gv.jobs)
// create an http.Server instance and specify our job manager as
// the handler for requests.
server := http.Server{
Handler: &gv,
Addr: ":8888",
}
// start server and accept connections.
log.Fatal(server.ListenAndServe())
}

TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超3個(gè)贊
select
語(yǔ)句應(yīng)該在 goroutine 函數(shù)之外并阻止請(qǐng)求直到作業(yè)執(zhí)行結(jié)束或達(dá)到超時(shí)。
- 3 回答
- 0 關(guān)注
- 180 瀏覽
添加回答
舉報(bào)