Google App Engine ModuleHostname: не контекст App Engine
Я пытаюсь обнаружить другие развернутые службы в App Engine. Нечто подобное предлагает эта статья.
Вот как выглядит мой код:
import (
"fmt"
"net/http"
"google.golang.org/appengine"
)
func ServiceHostname(serviceName string, r *http.Request) (string, error) {
ctx := appengine.NewContext(r)
hostname, err := appengine.ModuleHostname(ctx, serviceName, "", "")
if err != nil {
return "", fmt.Errorf("unable to find service %s: %v", serviceName, err)
}
return hostname, nil
}
Я вызываю эту функцию в обычном http-обработчике. Я получил ошибку: not an App Engine context
,
Единственная разница между моим кодом и ссылочной статьей в версии движка приложения. Я использую новый go111
где он использует go1
во время выполнения.
Вы знаете, как преодолеть проблему?
2 ответа
Я нашел решение. Вам нужно позвонить appengine.Main()
в вашем основном файле, хотя это не должно быть необходимо делать в новом go111
во время выполнения.
Таким образом, рассматриваемый код остается тем же, вам нужно зарегистрировать ваши обработчики так же, как в go1.9
во время выполнения.
func main() {
http.HandleFunc("/serveurl", handle)
appengine.Main()
}
Источник: https://groups.google.com/d/msg/google-appengine-go/ZcASFMWJKpE/7iwGirNiBgAJ
Это также упоминается в разделе " Написание основного пакета":
- Или, если ваш сервис использует
google.golang.org/appengine
пакет, включите звонок вappengine.Main()
,
Насколько я понимаю, эта ошибка возвращается, когда ваше приложение AppEngine имеет среду выполнения, установленную на go111, и приложение импортирует любой из пакетов "google.golang.org/appengine", например log, urlfetch, memcache и т. Д., Но приложение не вызовите метод "appengine.Main".
Поэтому вы можете выбрать любую реализацию ниже:
import (
"fmt"
"net/http"
"google.golang.org/appengine"
)
func init() {
// register handlers
http.HandleFunc(“/“, indexHandler)
appengine.Main()
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
.......handle the request.......
}
func ServiceHostname(serviceName string, r *http.Request) (string, error) {
ctx := appengine.NewContext(r)
hostname, err := appengine.ModuleHostname(ctx, serviceName, "", "")
if err != nil {
return "", fmt.Errorf("unable to find service %s: %v", serviceName, err)
}
return hostname, nil
}
Или откажитесь от всех пакетов appengine:
import (
"fmt"
“log”
"net/http"
“os”
)
func main() {
port := os.Getenv(“PORT”)
if port == “” {
port = “8080”
}
http.HandleFunc(“/“, indexHandler)
log.Fatal(http.ListenAndServe(“:”+port, Nil)
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
.....handle request....
}
Статья, на которую вы ссылались, была написана с учетом стандартной среды 1-го поколения, 2-го поколения (go111) в то время не было:
10 октября 2018 г.
Go runtime notes
Среда выполнения Go 1.11 для стандартной среды App Engine сейчас находится в стадии бета-тестирования. Доступно руководство по переносу приложений с Go 1.9 на Go 1.11.
Различия между двумя поколениями значительны (для всех языков, а не только для го). В разделе Миграция из App Engine Go SDK (необязательно) руководства по миграции я заметил:
- использование
request.Context()
или ваш предпочтительный контекст вместо использованияappengine.NewContext
,
Что может быть связано с вашей ошибкой. Но я на самом деле не пользователь Go, это всего лишь теория:)