Fetching a URL From the init() func in Go on AppEngine

。_饼干妹妹 提交于 2019-12-19 10:19:21

问题


Background: I'm running Go on GAE and using Mux for my router. In order to fetch a URL GAE requires that I use its built in urlFetch capability. I want to make this URL fetch happen during my modules init() but as far as I can tell I can only use urlFetch when invoked via a handler.

func init() {
  r := mux.NewRouter()
  r.HandleFunc("/", homeHandler)
  r.HandleFunc("/about", anotherHandler)
  http.Handle("/", r)
}

GAE suggests the following code for making a urlFetch:

c := appengine.NewContext(r)
client := urlfetch.Client(c)

... but its argument is an http router, and it doesn't want to work if I pass my mux router. So I'm out of ideas of how to make this urlFetch happen outside the scope of a URL handler.

Error when passing the mux router: "cannot use r (type *mux.Router) as type *http.Request in argument to "appengine".NewContext"


回答1:


You can't use AppEngine services that require a Context outside of handlers (because the creation of a Context requires an *http.Request value). This by nature means you can't use them in package init() functions either.
Note that you can use them from cron jobs and tasks added to task queues, because tasks and cron jobs are executed by issuing HTTP GET requests.

You have to restructure your code so that the service (urlFetch in your case) gets called from a handler.

A possible solution is to check if init completed in handlers that serve user requests. If not, perform the initialization function you would otherwise put in init() before proceeding to serve the request.

Yes, this may cause first requests to take considerably longer to serve. For this purpose (to avoid this) I recommend you to utilize Warmup requests. A warmup request is issued to a new instance before it goes "live", before it starts serving user requests. In your app.yaml config file you can enable warmup requests by adding -warmup to the inbound_services directive:

inbound_services:
  - warmup

This will cause the App Engine infrastructure to first issue a GET request to /_ah/warmup. You can register a handler to this URL and perform initialization tasks. As with any other request, you will have an http.Request in the warmup handler.

But please note that:

..you may encounter loading requests, even if warmup requests are enabled in your app.

Which means that in rare cases it may happen a new instance will not receive a warmup request, so its best to check initialization state in user handlers too.



来源:https://stackoverflow.com/questions/29912318/fetching-a-url-from-the-init-func-in-go-on-appengine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!