2013-03-01 26 views

Odpowiedz

13

Nie ma odpowiednika Go dla asynchronicznych API języka Python lub Java dla dowolnej usługi AppEngine. W rzeczywistości biblioteka standardowa Go również nie ma nic w standardowym stylu asynchronicznym. Powodem jest to, że w Go, piszesz funkcje używając stylu blokowania i komponujesz je używając podstawowych prymitywów współbieżnościowych w zależności od potrzeb. Chociaż nie można po prostu przydzielić go na początku połączenia dastore.Get, nadal jest to stosunkowo proste. Rozważmy następujący, contrived przykład:

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 
} 

To samo podejście można stosować w prawie każdym kontekście, w którym trzeba uruchomić więcej niż jedną rzecz, która może zająć trochę czasu w tym samym czasie, czy to wezwanie magazyn danych, urletch, ładowanie pliku itp.

+0

Jak to działa, skoro aplikacje Go na GAE działają w jednym wątku? –

+2

Środowisko wykonawcze Go multipleksuje wiele goroutines na jednym wątku systemu operacyjnego. W rzeczywistości wartością domyślną nawet poza AppEngine jest GOMAXPROCS = 1, co oznacza, że ​​tylko jeden goroutine będzie aktywnie uruchamiał twój kod. Mimo to środowisko uruchomieniowe przełącza się między goroutinami, gdy komunikują się, blokują, uruchamiają syscall lub czekają na blokadę. –

+0

Dzięki. Czy istnieje nawet korzyść z wydajności, jeśli działają w jednym wątku? Wybacz mi moją ignorancję. Edycja: Wydaje mi się, że korzyści związane z wydajnością będą pochodzić z wykonania kodu Go podczas oczekiwania na wywołanie I/O, aby powrócić? –

2

Nie ma jawnego API dla asynchronizatora w Go. Zamiast tego powinieneś użyć procedur go. Nie widziałem żadnego źródła na ten temat, ale podejrzewam, że nie ma tam async API z powodu łatwości używania procedur go.

Powiązane problemy