HTTP calls in App's init or start method corrupt Event Loop
Opened this issue · 1 comments
The below sample app starts, runs and answers requests, but some timeout (about 30%):
#!/usr/bin/python
# -*- coding: utf-8 -*-
import appier
import appier_extras
class App(appier.WebApp):
def __init__(self, *args, **kwargs):
appier.WebApp.__init__(
self, name="app", parts=(appier_extras.AdminPart,), *args, **kwargs
)
self._load_scales()
@appier.route("/bundles", "GET")
def get_bundles(self):
return self.bundles
def _load_scales(self):
url = "https://api.github.com/"
result = appier.get(url)
locales = {"en_us": result}
for locale, bundle in appier.legacy.iteritems(locales):
self._register_bundle(bundle, locale, context="scales")
if __name__ == "__main__":
app = App()
app.serve()
However, the following has no issues:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import appier
import appier_extras
class App(appier.WebApp):
def __init__(self, *args, **kwargs):
appier.WebApp.__init__(
self, name="app", parts=(appier_extras.AdminPart,), *args, **kwargs
)
self._load_scales()
@appier.route("/bundles", "GET")
def get_bundles(self):
return self.bundles
def _load_scales(self):
locales = {"en_us": {"current_user_url": "https://api.github.com/user"}}
for locale, bundle in appier.legacy.iteritems(locales):
self._register_bundle(bundle, locale, context="scales")
if __name__ == "__main__":
app = App()
app.serve()
In my local development machine, both work. In my docker deployed app, the first fails and the second works.
We had an hypothesis where the HTTP call in the init method was invalid since the event loop was still warming up. We replaced the appier.get call for a requests.get (python requests lib) and it worked:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import appier
import appier_extras
class App(appier.WebApp):
def __init__(self, *args, **kwargs):
appier.WebApp.__init__(
self, name="app", parts=(appier_extras.AdminPart,), *args, **kwargs
)
self._load_scales()
@appier.route("/bundles", "GET")
def get_bundles(self):
return self.bundles
def _load_scales(self):
import requests
url = "https://api.github.com/"
result = requests.get(url)
result = result.json()
locales = {"en_us": result}
for locale, bundle in appier.legacy.iteritems(locales):
self._register_bundle(bundle, locale, context="scales")
if __name__ == "__main__":
app = App()
app.serve()
This is an issue whether the HTTP remote call is made in the init method or the start method. I would assume Appier's thread pool manager is still warming up and such an early HTTP call is corrupting it in some way.
@joao-conde wanna jump into a call to discuss this one? I may have some free time latter this week.