GAE Go - 异步数据存储API?

6

是否有类似于Python/Java的异步数据存储API的Go语言版本?或者只能使用带有go关键字的普通API呢?

2个回答

13

对于任何AppEngine服务,Go没有与Python或Java异步API相对应的等效API。事实上,Go标准库也没有标准的异步风格。原因是在Go中,你使用阻塞式编写函数,并根据需要使用一些基本的并发原语来组合它们。虽然你不能仅仅在dastore.Get调用之前添加go,但这仍然是相对简单的。例如,考虑以下刻意构造的示例:

func loadUser(ctx appengine.Context, name strings) (*User, err) {
  var u User
  var entries []*Entry
  done := make(chan error)

  go func() {
    // Load the main features of the User
    key := datastore.NewKey(ctx, "user", name, 0, nil)
    done <- datastore.Get(ctx, key)
  }()

  go func() {
    // Load the entries associated with the user
    q := datastore.NewQuery("entries").Filter("user", name)
    keys, err := q.GetAll(ctx, &entries)
    for i, k := range keys {
      entries[i].key = k
    }
    done <- err
  }()

  success := true
  // Wait for the queries to finish in parallel
  for i := 0; i < 2 /* count the funcs above */; i++ {
    if err := <-done; err != nil {
      ctx.Errorf("loaduser: %s", err)
      success = false
    }
  }
  if !success {
    return
  }

  // maybe more stuff here
}

这种方法可以在几乎任何需要同时运行多个可能需要一些时间的操作的情况下使用,无论是数据存储调用、urlfetch、文件加载等。

йүҙдәҺGAEдёҠзҡ„Goеә”з”ЁзЁӢеәҸеңЁеҚ•дёӘзәҝзЁӢдёҠиҝҗиЎҢпјҢйӮЈд№ҲиҝҷжҳҜеҰӮдҪ•е·ҘдҪңзҡ„пјҹ - Matthew H
2
Go运行时将许多goroutine复用到单个操作系统线程上。事实上,即使在AppEngine之外,默认值也是GOMAXPROCS=1,这意味着只有一个goroutine会主动运行您的代码。然而,尽管如此,当它们通信、阻塞、执行系统调用或等待锁时,运行时仍会在goroutine之间来回切换。 - Kyle Lemons
谢谢。那么,如果它们在单线程上运行,是否会有性能优势呢?请原谅我的无知。编辑:我猜性能优势将来自于Go在等待I/O调用返回时执行代码的能力? - Matthew H
2
没错。运行时会来回切换,以便在有可运行项的情况下始终有运行中的内容。 - Kyle Lemons

2

Go语言中没有显式的异步API,需要使用go协程实现。我没有看到任何关于这方面的资料,但我猜测不提供异步API是因为使用go协程非常容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接