通过通道处理HTTP请求的模式

时间:2018-11-18 08:12:54

标签: go

我正在编写一个运行了很长时间的goroutine的Web应用程序。 我想通过通道将所有HTTP请求委托给此goroutine。 我遇到的模式是:

// Internal long running goroutine
for{
  select{
  case e := <-event: //web request
    req := e.req
    // do something
    ....
    select {
    case <-ctx.Done():
       //log  
    default: 
      e.replyTo <- result
    }
  }
}

// Web handler
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
  //decode request etc
  ...

  replyTo := make(chan interface{}, 1)
  ctx, cancel := context.WithCancel(context.BackGround())
  event <- Event{req: req, ctx: ctx, replyTo: replyTo}
  select{
  case <-time.After(time.Second):
     cancel()
     //return 500
  case r := <-replyTo:
    // return some response
  }
})

我确实看到最后只有一个go例程,所以失去了并行性,但是我对此表示同意。

此模式是否正确? 还有什么其他方法可以建议?

1 个答案:

答案 0 :(得分:1)

  

这种模式是正确的方法吗?

假设您尝试在一个go例程中管理状态,我会说。我认为最好有某种形式的状态管理器来负责线程安全。因此,处理程序应该采用可以管理状态的内容,并向处理程序简单地公开一些方法。

type State interface{
  Load() (string, error)
  Save(something string) error
}

解耦代码将在以后为您带来回报。它还将允许对处理程序和状态进行单元测试,使其具有重点和可读性。

相关问题