Czy istnieje analogiczny algorytm Go do asynchronicznych API datastore Pythona/Javy? A może po prostu użyć zwykłego API ze słowem kluczowym go
?GAE Go - Async Datastore API?
Odpowiedz
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.
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.
Jak to działa, skoro aplikacje Go na GAE działają w jednym wątku? –
Ś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ę. –
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ć? –