比如这段是这样子的回调,http.HandleFunc("/", payloadHandler), 只是把一个 http 请求塞进 chan chan Job 里,可能并没有等到处理就返回给请求 200 了。
func payloadHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
w.WriteHeader( http.StatusMethodNotAllowed)
return
}
// Read the body into a string for json decoding
var content = &PayloadCollection{}
err := json.NewDecoder(io.LimitReader(r.Body, MaxLength)).Decode(&content)
if err != nil {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader( http.StatusBadRequest)
return
}
// Go through each payload and queue items individually to be posted to S3
for _, payload := range content.Payloads {
// let's create a job with the payload
work := Job{Payload: payload}
// Push the work onto the queue.
JobQueue <- work
}
w.WriteHeader( http.StatusOK)
}
到了从双层队通道取 Job 时候,处理的结果并不会通知给 http 请求方,
// Start method starts the run loop for the worker, listening for a quit channel in
// case we need to stop it
func (w Worker) Start() {
go func() {
for {
// register the current worker into the worker queue.
w.WorkerPool <- w.JobChannel
select {
case job := <-w.JobChannel:
// we have received a work request.
if err := job.Payload.UploadToS3(); err != nil {
log.Errorf("Error uploading to S3: %s", err.Error())
}
case <-w.quit:
// we have received a signal to stop
return
}
}
}()
}
我是想实现能实时支持的方式,还把w http.ResponseWriter
也套进了 Job 里面,想等真正有结果在w.Write
。
结果发现接受的不到 Response.Body。应该是返回比处理要早。
所以不知道是不是这种模式 ,只能实现异步。
1
gfreezy 2018-09-29 19:25:37 +08:00
原文跟 go 没啥关系啊。收到请求入队列,然后开一大波 worker 处理。只要队列扛得住,不停加 worker 就可以了。跟 go 没啥关系,而且都是 io bound 的,ruby 完全也可以达到这个效果
|