Créer des gestionnaires de tâches

Cette page explique comment créer un gestionnaire de tâches, c'est-à-dire le code qui gère une tâche d'envoi. Vous devez fournir un gestionnaire de requêtes pour traiter la tâche. Le mappage de l'URL de requête au gestionnaire approprié est déclaré dans le fichier app.yaml de votre service, comme tout autre gestionnaire de requêtes. Comme vous contrôlez la manière de mapper les requêtes de tâches à un gestionnaire, vous êtes libre d'organiser vos gestionnaires de tâches comme vous le souhaitez. Si votre application traite de nombreux types de tâches, vous pouvez ajouter tous les gestionnaires à un seul service ou les répartir entre plusieurs services.

Écrire un gestionnaire de requêtes de tâches d'envoi

Dans la file d'attente, le service Task Queue crée un en-tête HTTP et l'envoie à une instance du service de nœud de calcul spécifié par la cible de la tâche. Les requêtes Task Queue sont envoyées à partir de l'adresse IP 0.1.0.2.

Il n'est pas nécessaire d'écrire le code du gestionnaire avec le même langage que celui qui a été utilisé pour créer la tâche et la mettre en file d'attente s'il se trouve dans un service distinct.

Suivez ces instructions lorsque vous écrivez le code de votre gestionnaire :

  • Le code doit renvoyer un code d'état HTTP compris entre 200 et 299 pour indiquer la réussite de la tâche. Tout autre code indique que la tâche a échoué.

  • Les tâches d'envoi ont un délai d'exécution fixe qui dépend du type de scaling du service qui les exécute. Les services de scaling automatique doivent s'achever au plus tard 10 minutes plus tard. Scaling manuel et de base : les requêtes peuvent durer jusqu'à 24 heures. Si le gestionnaire ne respecte pas le délai, le service Task Queue suppose que la tâche a échoué et tente une nouvelle exécution.

    Lorsque l'exécution d'une tâche approche de l'échéance, App Engine lève une exception DeadlineExceededError avant ce délai (à partir du module google.appengine.runtime), afin que vous puissiez enregistrer votre travail ou consigner toute progression réalisée.

  • Le gestionnaire doit être idempotent. L'API Task Queue d'App Engine est conçue pour assurer une distribution de type "au moins une fois". En d'autres termes, si une tâche est ajoutée avec succès, App Engine la transmet à un gestionnaire au moins une fois. Notez que dans certaines circonstances rares, l'exécution de plusieurs tâches est possible. Le code doit donc garantir qu'une exécution répétée n'entraîne pas d'effets secondaires néfastes.

L'exemple suivant montre l'extraction d'une valeur entière à partir d'une requête et l'ajout de la valeur à un compteur géré dans Cloud Datastore :


from google.appengine.ext import ndb
import webapp2

COUNTER_KEY = 'default counter'

class Counter(ndb.Model):
    count = ndb.IntegerProperty(indexed=False)

class UpdateCounterHandler(webapp2.RequestHandler):
    def post(self):
        amount = int(self.request.get('amount'))

        # This task should run at most once per second because of the datastore
        # transaction write throughput.
        @ndb.transactional
        def update_counter():
            counter = Counter.get_or_insert(COUNTER_KEY, count=0)
            counter.count += amount
            counter.put()

        update_counter()

app = webapp2.WSGIApplication([
    ('/update_counter', UpdateCounterHandler)
], debug=True)

Le mappage de l'URL de la tâche /update-counter à la classe UpdateCounterHandler est effectué dans WSGIApplication.

Le fichier worker.yaml crée un service nommé "worker" (nœud de calcul) et y ajoute le code correspondant. Notez que l'URL du gestionnaire est sécurisée, car le paramètre login:admin est spécifié :

runtime: python27
api_version: 1
threadsafe: true
service: worker

handlers:
- url: /.*
  script: worker.app
  login: admin

Le service Task Queue utilise le code HTTP de la réponse du gestionnaire pour déterminer si la tâche a abouti. La réponse du gestionnaire n'est visible que par le service Task Queue et ne sert qu'à déterminer si la tâche a abouti. La file d'attente ignore tous les autres champs de la réponse. Ensuite, le service supprime la réponse. L'application d'origine ne reçoit jamais de données. Si une tâche échoue, le service Task Queue la retente en envoyant une autre requête.

Les données fournies par l'utilisateur peuvent être distribuées au gestionnaire dans la requête sous forme de chaîne de requête ou de charge utile dans le corps de la requête. L'insertion de données utilisateur est décrite dans la section Créer des tâches. Si la requête inclut des données, le gestionnaire doit savoir comment elles y ont été insérées. Le code exact utilisé pour extraire les données de la requête dépend du framework Web que vous utilisez.

Pour tester un gestionnaire de tâches, connectez-vous en tant qu'administrateur et accédez à son URL depuis votre navigateur.

Lire les en-têtes de requêtes

Une requête HTTP de tâche d'envoi comporte des en-têtes spéciaux définis par App Engine qui contiennent des informations spécifiques à la tâche que votre gestionnaire peut utiliser.

Si ces en-têtes sont présents dans une requête d'utilisateur externe à votre application, ils sont supprimés et remplacés. La seule exception concerne les requêtes des administrateurs connectés à l'application, qui sont autorisés à définir des en-têtes à des fins de test. En revanche, les en-têtes ne sont pas supprimés lorsque votre application est en cours d'exécution sur le serveur de développement.

Les requêtes de Task Queue contiennent toujours les en-têtes suivants :

En-tête Description
X-AppEngine-QueueName Nom de la file d'attente (éventuellement "default" pour la file d'attente d'envoi par défaut).
X-AppEngine-TaskName Nom de la tâche ou identifiant unique généré par le système si aucun nom n'a été spécifié.
X-AppEngine-TaskRetryCount Nombre de fois où une tâche a fait l'objet de nouvelles tentatives d'exécution. Pour la première tentative, cette valeur est définie sur 0. Ce chiffre inclut les tentatives lorsque la tâche a échoué en raison d'un manque d'instances disponibles et n'a jamais atteint la phase d'exécution.
X-AppEngine-TaskExecutionCount Nombre de fois où cette tâche a précédemment échoué pendant la phase d'exécution. Ce chiffre n'inclut pas les échecs dus à un manque d'instances disponibles.
X-AppEngine-TaskETA Heure d'exécution cible de la tâche, spécifiée en secondes depuis le 1er janvier 1970.

Si le gestionnaire de requêtes trouve l'un des en-têtes répertoriés ci-dessus, il peut valider qu'il s'agit d'une requête Task Queue.

De plus, les requêtes Task Queue peuvent contenir les en-têtes suivants :

En-tête Description
X-AppEngine-TaskPreviousResponse Code de réponse HTTP de la tentative précédente.
X-AppEngine-TaskRetryReason Raison de la nouvelle tentative d'exécution de la tâche.
X-AppEngine-FailFast Indique qu'une tâche en cours échoue immédiatement si une instance existante n'est pas disponible.

Sécuriser les URL du gestionnaire de tâches

Si une tâche effectue des opérations sensibles (telles que la modification de données), vous souhaiterez peut-être sécuriser l'URL du gestionnaire pour éviter qu'un utilisateur externe malveillant ne l'appelle directement. Vous pouvez empêcher les utilisateurs d'accéder aux URL de tâches en limitant l'accès aux administrateurs App Engine. Les requêtes de tâches elles-mêmes sont émises par App Engine et peuvent toujours cibler une URL restreinte.

Vous pouvez restreindre une URL en ajoutant l'élément login: admin à la configuration du gestionnaire dans le fichier app.yaml.

Exemple :

handlers:
- url: /your-task
  script: worker.app
  login: admin

Étape suivante

Cette page vous a-t-elle été utile ? Évaluez-la :

Envoyer des commentaires concernant…

Environnement standard App Engine pour Python 2