比如这段是这样子的回调,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。应该是返回比处理要早。
所以不知道是不是这种模式 ,只能实现异步。
|  |      1gfreezy      2018-09-29 19:25:37 +08:00 原文跟 go 没啥关系啊。收到请求入队列,然后开一大波 worker 处理。只要队列扛得住,不停加 worker 就可以了。跟 go 没啥关系,而且都是 io bound 的,ruby 完全也可以达到这个效果 | 
|  |      2arthurblake      2018-09-30 11:31:34 +08:00 @gfreezy 你没明白楼主的意思,楼主意思是在 worker 里面处理完消息后,还要把消息结果通过 http 返回给调用方。 |