2013-03-01 2 views

ответ

13

Существует нет Go эквивалентно асинхронным API-интерфейсам Python или Java для любой службы AppEngine. Фактически, стандартная библиотека Go не имеет ничего в стандартном асинхронном стиле. Причина в том, что в Go вы пишете функции, используя стиль блокировки, и составляете их, используя некоторые базовые примитивы параллелизма, основанные на потребности. Хотя вы не можете просто нажать go в начале вызова dastore.Get, он по-прежнему относительно прост. Рассмотрим следующий, надуманный пример:

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, загрузка файла и т. д.

+0

Как это работает, учитывая, что приложения Go на GAE работают в одном потоке? –

+2

The Go runtime мультиплексирует множество goroutines на один поток операционной системы. Фактически, по умолчанию даже вне AppEngine GOMAXPROCS = 1, что означает, что только один goroutine будет активно запускать ваш код. Тем не менее, несмотря на это, среда выполнения будет переключаться между goroutines, когда они обмениваются данными, блокируют, выполняют системный вызов или ждут блокировки. –

+0

Спасибо. Таким образом, есть ли даже преимущество в производительности, если они работают на одном потоке? Простите мое невежество. Редактировать: Я полагаю, что преимущество в производительности будет зависеть от исполняемого кода Go, пока он ждет возврата вызова ввода-вывода? –

2

Нет явного API для async в Go. Вместо этого вы должны использовать подпрограммы. Я не видел никаких источников на этом, но я подозреваю, что асинхронный API не существует из-за того, насколько легко использовать подпрограммы go.

Смежные вопросы