Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GAE Go — Async datastore API?

Is there a Go analogue to Python/Java's async datastore APIs? Or can one just use the normal API with the go keyword?

like image 521
Matthew H Avatar asked Mar 01 '13 19:03

Matthew H


1 Answers

There is no Go equivalent to the Python or Java asynchronous APIs for any AppEngine service. In fact, the Go standard library has nothing in the standard asynchronous style either. The reason is that in Go, you write functions using a blocking style and compose them using some basic concurrency primitives based on need. While you cannot just tack go at the beginning of a dastore.Get call, it is still relatively straightforward. Consider the following, contrived example:

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
}

This same approach can be used in pretty much any context in which you need to run more than one thing that might take awhile at the same time, whether it's a datastore call, urlfetch, file load, etc.

like image 193
Kyle Lemons Avatar answered Sep 20 '22 02:09

Kyle Lemons