背景:我正在运行Go on GAE并使用Mux作为我的路由器。为了获取URL,GAE要求我使用其内置的urlFetch功能。我希望在我的模块init()期间进行这个URL提取,但据我所知,我只能在通过处理程序调用时使用urlFetch。
func init() {
r := mux.NewRouter()
r.HandleFunc("/", homeHandler)
r.HandleFunc("/about", anotherHandler)
http.Handle("/", r)
}
GAE建议使用以下代码来制作urlFetch:
c := appengine.NewContext(r)
client := urlfetch.Client(c)
...但它的参数是一个http路由器,如果我通过我的mux路由器它不想工作。所以我不知道如何使这个urlFetch发生在URL处理程序的范围之外。
传递多路复用路由器时出错:“不能使用r(类型* mux.Router)作为类型* http.Request参数”appengine“.NewContext”
答案 0 :(得分:4)
您无法使用需要Context
处理程序之外的AppEngine服务(因为创建Context
需要*http.Request
值)。这本质上意味着您不能在包init()
函数中使用它们
请注意,您可以从cron作业和添加到任务队列的任务中使用它们,因为任务和cron作业是通过发出HTTP GET请求来执行的。
您必须重新构建代码,以便从处理程序调用服务(在您的情况下为urlFetch)。
一种可能的解决方案是检查init是否在处理用户请求的处理程序中完成。如果没有,请执行初始化功能,否则在继续提供请求之前将其放入init()
。
是的,这可能会导致第一次请求需要花费更长的时间才能完成。为此(为避免这种情况),我建议您使用Warmup requests。在新实例开始提供用户请求之前,它会在“实时”之前发出一个预热请求。在app.yaml
配置文件中,您可以通过向-warmup
指令添加inbound_services
来启用预热请求:
inbound_services:
- warmup
这将导致App Engine基础架构首先向GET
发出/_ah/warmup
请求。您可以向此URL注册处理程序并执行初始化任务。与任何其他请求一样,您将在预热处理程序中拥有http.Request
。
但请注意:
..即使您的应用中启用了热身请求,您也可能会遇到loading requests。
这意味着在极少数情况下可能会发生新实例不会收到预热请求,因此最好也检查用户处理程序中的初始化状态。