【问题标题】:Benefits of actor pattern in HTTP handlerHTTP处理程序中actor模式的好处
【发布时间】:2018-08-26 18:56:31
【问题描述】:

我一直在阅读一些 go 博客,最近我偶然发现了 Peter Bourgon 题为“做事方式”的演讲。他展示了 GO 中并发执行者模式的一些示例。这是一个使用这种模式的处理程序示例:

func (a *API) handleNext(w http.ResponseWriter, r *http.Request) {
    var (
        notFound   = make(chan struct{})
        otherError = make(chan error)
        nextID     = make(chan string)
    )
    a.action <- func() {
        s, err := a.log.Oldest()
        if err == ErrNoSegmentsAvailable {
            close(notFound)
            return
        }
        if err != nil {
            otherError <- err
            return
        }
        id := uuid.New()
        a.pending[id] = pendingSegment{s, time.Now().Add(a.timeout), false}
        nextID <- id
    }
    select {
    case <-notFound:
        http.NotFound(w, r)
    case err := <-otherError:
        http.Error(w, err.Error(), http.StatusInternalServerError)
    case id := <-nextID:
        fmt.Fprint(w, id)
    }
}

在后台监听action 频道有一个循环:

func (a *API) loop() {
    for {
        select {
        case f := <-a.action:
            f()
        }
    }
}

我的问题是这一切有什么好处?处理程序并没有更快,因为它仍然处于阻塞状态,直到 action func 中的某些操作返回一些内容。这与从 go 例程外部返回函数本质上是一样的。我在这里错过了什么?

【问题讨论】:

  • 第一次听说“演员模式”,我知道“演员模型”,但很少涉及,可以链接到原文吗?

标签: go concurrency


【解决方案1】:

好处不是单个调用,而是所有调用的总和。

例如,您可以使用它来将实际执行限制为单个 goroutine,从而避免并发执行带来的所有问题。

例如,我使用此模式将连接的所有使用同步到与串行通信的硬件设备。

【讨论】:

  • 你能再扩展一点吗?在上面的示例中,不是首先因为 go 例程才需要与单个函数调用者同步吗?如果单独作为“同步”处理程序,它不会产生同样的效果吗?
  • @Rodrigo 这些动作在运行 API.loop() 的单个 goroutine 中执行。如果操作直接在处理程序中调用,那么这些操作会在 net/http 服务器启动的每个连接的 goroutines 中并发运行。
猜你喜欢
  • 2011-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多