2016-08-10 2 views
0

Also machte ich einen Cron-Job, um meine News Aggregator App mit neuen Geschichten alle 1 Minute zu aktualisieren. Ich sollte sagen, ich bin ein absoluter Neuling für Cron-Jobs, mit sehr begrenzter Erfahrung mit GAE.Problem mit laufenden Cron-Job in GAE Python

Dies ist meine Ordnerstruktur:

  • news.py
  • index.yaml
  • feedparser.py
  • cron.yaml
  • app.yaml
  • Vorlagen
  • statisch

Dies ist, was in news.py ist:

feed = ['https://news.google.co.in/news/section?cf=all&pz=1&ned=in&topic=e&ict=ln&output=rss&num=10'] 

feedlist = [] 

def render_str(template, **params): 
    t = jinja_env.get_template(template) 
    return t.render(params) 

class CronTask(webapp2.RequestHandler): 
    def get(self): 
     self.redirect('/entertainment') 

class MainPage(webapp2.RequestHandler): 
    def get(self): 
     self.response.write(render_str('mainpage.html')) 

class Entertainment(webapp2.RequestHandler): 
    def get(self): 
     rssfeed = feedparser.parse(feed) 
     for news in rssfeed.entries: 
      new_entry = {'title': news.title, 'url': news.link, 'publisheddate': news.published} 
      feedlist.append(new_entry) 
     self.redirect('/1/display') 

class Display(webapp2.RequestHandler): 
    def get(self, page_no): 
     is_this_last = False 
     list_to_be_displayed_here = feedlist[(int(page_no)-1)*5:int(page_no)*5] 
     try: 
      is_last = feedlist[int(page_no)*5] 
     except: 
      is_this_last = True 
     self.response.write(render_str('/display.html', page_no=page_no, feedlist=list_to_be_displayed_here, is_this_last=is_this_last)) 

app = webapp2.WSGIApplication([('/', MainPage), 
          ('/entertainment', Entertainment), 
          ('/([0-9]+)/display', Display), 
          ('/crontask', CronTask) 
          ], debug = True) 

Ich nehme an, das ist, wie cron.yaml eingerichtet werden soll soll:

cron: 
- description: periodic update of news 
    url: /crontask 
    target: beta 
    schedule: every 1 minute 

Dies ist app.yaml:

application: encoded-alpha-139800 
version: 1 
runtime: python27 
api_version: 1 
threadsafe: true 

handlers: 
- url: /static 
    static_dir: static 

- url: /crontask 
    script: news.py 

- url: /.* 
    script: news.app 

libraries: 
- name: jinja2 
    version: latest 

display.html zeigt nur die Infos der Feeds an und da ich nicht wusste, wie man die cursor() implementiert Methode, ich implementiert die rudimentäre Paginierung, die Sie in get() von Display sehen, mit mir schneiden feedlist.

Als ich news.py laufen, ich diese Zurückverfolgungs erhalten:

File "C:\Program Files (x86)\Google\google_appengine\dev_appserver.py", line 83, in <module> 
_run_file(__file__, globals()) 
    File "C:\Program Files (x86)\Google\google_appengine\dev_appserver.py", line 79, in _run_file 
execfile(_PATHS.script_file(script_name), globals_) 
    File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\devappserver2.py", line 1040, in <module> 
main() 
    File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\devappserver2.py", line 1033, in main 
dev_server.start(options) 
    File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\devappserver2.py", line 758, in start 
options.config_paths, options.app_id) 
    File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\application_configuration.py", line 831, in __init__ 
module_configuration = ModuleConfiguration(config_path, app_id) 
    File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\application_configuration.py", line 127, in __init__ 
self._config_path) 
    File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\application_configuration.py", line 424, in _parse_configuration 
config, files = appinfo_includes.ParseAndReturnIncludePaths(f) 
    File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\appinfo_includes.py", line 82, in ParseAndReturnIncludePaths 
appyaml = appinfo.LoadSingleAppInfo(appinfo_file) 
    File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\appinfo.py", line 2190, in LoadSingleAppInfo 

listener.Parse(app_info) 
    File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\yaml_listener.py", line 227, in Parse 
self._HandleEvents(self._GenerateEventParameters(stream, loader_class)) 
    File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\yaml_listener.py", line 178, in _HandleEvents 
raise yaml_errors.EventError(e, event_object) 
google.appengine.api.yaml_errors.EventError: threadsafe cannot be enabled with CGI handler: news.py 
    in "C:\Users\IBM_ADMIN\Downloads\7c\NewsAggregatorGAE\app.yaml", line 19, column 18 

Ist es, weil ich fast die gesamte Anwendung über einen cron-Job zu laufen bin versucht? Oder stimmt etwas nicht mit meinen Einstellungen oder meinem gesamten Setup überein?

Antwort

1

Das Problem ist, dass Sie den Handler angezeigt eine CGI-Anwendung in Ihrer app.yaml Datei zu sein:

script: news.py 

Von Request handlers:

When App Engine receives a web request for your application, it calls the handler script that corresponds to the URL, as described in the application's app.yaml configuration file . The Python 2.7 runtime supports the WSGI standard and the CGI standard for backwards compatibility. WSGI is preferred, and some features of Python 2.7 do not work without it. The configuration of your application's script handlers determines whether a request is handled using WSGI or CGI.

...

If you mark your application as thread-safe, concurrent requests will be enabled, which means that App Engine can dispatch multiple requests to each web server in parallel. To do so, set threadsafe: true in app.yaml. Concurrent requests are not available if any script handler uses CGI.

es nur eine WSGI App machen und dieser Fehler sollte gehen weg:

script: news.app 

Denken Sie daran, dass der GAE Cron-Dienst nicht ist Hing aber ein Generator für GET-Anfragen an die konfigurierten URLs gemäß dem konfigurierten Zeitplan. Von Scheduling Tasks With Cron for Python:

The App Engine Cron Service allows you to configure regularly scheduled tasks that operate at defined times or regular intervals. These tasks are commonly known as cron jobs. These cron jobs are automatically triggered by the App Engine Cron Service.

...

A cron job invokes a URL, using an HTTP GET request, at a given time of day. An cron job request is subject to the same limits as those for push task queues.

Wie Sie Ihre App die Jobs Cron führt wirklich läuft darauf hinaus, wie sie diese Anforderungen verarbeitet.

+0

Es gab jetzt keine Fehler. Aber es scheint nicht automatisch zu laufen. Ich startete den Server, ging zur Hauptseite, klickte auf den Link, um zu '\ entertainment' zu gehen, die News-Feeds kamen, aber dann wartete ich auf etwa 3 Minuten und trotzdem wurde die Seite nicht neu geladen und ich sah auch keine neuen Protokolle. –

+0

Auf dem Entwicklungsserver muss er manuell ausgelöst werden. Klicken Sie auf der Seite "Cron-Jobs" auf der Admin-Seite auf "Jetzt ausführen". –

+0

Es scheint also, dass 'cron.yaml' nicht auf dem Admin-Server geladen ist. Dies ist, was ich auf der 'Cron Jobs'-Seite bekomme -' EventError: Wert kann nicht alle 1 Minute dem Attribut 'schedule' zugeordnet werden Edit: Ah ja, ich denke ich muss "minutes" angeben, anstatt "Minute". –