Creazione di attività push

Questa pagina descrive come creare le attività e inserirle nelle code in modalità push. Quando Se vuoi elaborare un'attività, devi creare un nuovo oggetto dell'attività e posizionarlo in coda. Puoi specificare esplicitamente il servizio e il gestore che elaborano l'attività, e, facoltativamente, passare dati specifici dell'attività al gestore. Puoi anche ottimizza la configurazione dell'attività, ad esempio programmando un'ora nel futuro quando deve essere eseguita o limita il numero di volte in cui vuoi che l'attività in caso di errore.

Creazione di una nuova attività

Per creare e accodare un'attività, chiama la funzione taskqueue.add(). Il seguente codice crea un'attività che ha come target il servizio denominato worker e invoca il relativo gestore impostando l'URL /update-counter:

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

        task = taskqueue.add(
            url='/update_counter',
            target='worker',
            params={'amount': amount})

        self.response.write(
            'Task {} enqueued, ETA {}.'.format(task.name, task.eta))

In alternativa, puoi creare un oggetto Task e chiamarlo add().

Specifica del servizio worker

Quando un'attività viene rimossa dalla coda, il servizio Task Queue la inoltra a un servizio worker. Ogni attività ha un target e un url, che determinano il servizio e l'handler che alla fine eseguiranno l'attività.

target

La destinazione specifica il servizio che riceverà la richiesta HTTP per eseguire l'attività. È una stringa che specifica un servizio/una versione/un'istanza uno qualsiasi dei moduli canonici. I moduli più utilizzati sono:

    service
    version.service
    instance.version.service

La stringa di destinazione è anteposta al nome di dominio dell'app. Esistono tre tipi di modi per impostare la destinazione per un'attività:

  • Dichiara il target quando crei l'attività. Puoi impostare il target in modo esplicito utilizzando il parametro target in taskqueue.add() personalizzata. Vedi l'esempio riportato sopra.

  • Includi un'istruzione target quando definisci una coda nella queue.yaml, come nella definizione di queue-blue. Tutte le attività aggiunte a una coda con un target utilizzeranno quel target, anche se è stato assegnato un obiettivo diverso all'attività al momento della costruzione.

  • Se non viene specificato alcun target in base a uno dei due metodi precedenti, la destinazione della task è la versione del servizio che la mette in coda. Tieni presente che se inserisci in coda un'attività dal servizio e dalla versione predefiniti in questo modo e la versione predefinita cambia prima dell'esecuzione dell'attività, questa verrà eseguita nella nuova versione predefinita.

url

url seleziona uno dei gestori nel servizio di destinazione, che eseguire l'attività.

url deve corrispondere a uno dei pattern URL del gestore nel target completamente gestito di Google Cloud. url può includere parametri di ricerca se il metodo specificato nell'attività è GET o PULL. Se non viene specificato url, viene utilizzato l'URL predefinito /_ah/queue/[QUEUE_NAME], dove [QUEUE_NAME] è il nome della fila della task.

Trasferimento dei dati all'handler

Puoi passare i dati al gestore come parametri di ricerca nell'URL dell'attività, ma solo se il metodo specificato nell'attività è GET o PULL.

Puoi anche utilizzare uno qualsiasi dei seguenti campi per aggiungere dati a un'attività:

  • payload, che consegna i dati delle attività nel corpo della richiesta HTTP.
  • params

Queste tre chiamate sono equivalenti:

taskqueue.add(method=GET, url='/update-counter?key=blue', target='worker')
taskqueue.add(url='/update-counter', params={'key': 'blue'}, target='worker')
taskqueue.add(url='/update-counter', payload="{'key': 'blue'}", target='worker')

Assegnare un nome a un'attività

Quando crei una nuova attività, App Engine assegna un nome univoco per impostazione predefinita. Tuttavia, puoi assegnare il tuo nome a un'attività utilizzando il parametro name. Un vantaggio di assegnare nomi alle tue attività è che le attività con nome vengono deduplicate, quindi puoi utilizzare i nomi delle attività garantire che un'attività venga aggiunta una sola volta. La deduplica continua per 9 giorni dopo il completamento o l'eliminazione della task.

Tieni presente che la logica di deduplica introduce un overhead significativo delle prestazioni, con un conseguente aumento delle latenze e potenzialmente dei tassi di errore associati alle attività con nome. Questi costi possono aumentare notevolmente se i nomi delle attività sono sequenziali, ad esempio con i timestamp. Pertanto, se assegni i tuoi nomi, consigliamo di utilizzare un prefisso ben distribuito per i nomi delle attività, ad esempio un hash dei contenuti.

Se assegni i tuoi nomi alle attività, tieni presente che la lunghezza massima del nome è 500 e il nome può contenere lettere maiuscole e minuscole, numeri trattini bassi e trattini.

taskqueue.add(url='/url/path', name='first-try')

Aggiunta delle attività in modo asincrono.

Per impostazione predefinita, le chiamate che aggiungono attività alle code sono sincrone. Per la maggior parte in scenari diversi, le chiamate sincrone vanno bene. L'aggiunta di un'attività a una coda è in genere per un'operatività veloce. Esiste una piccola percentuale di operazioni di aggiunta delle attività che richiede molto più tempo, ma il tempo medio per aggiungere un'attività è inferiore a 5 ms.

L'aggiunta di operazioni a code diverse non può essere suddivisa in batch, pertanto l'API Task Queue fornisce anche chiamate asincrone che consentono di aggiungere queste attività in parallelo, riducendo ulteriormente la latenza. Questo è utile se stai creando un un'applicazione estremamente sensibile alla latenza che deve eseguire diverse attività di aggiunta operazioni su diverse code contemporaneamente.

Se vuoi effettuare chiamate asincrone a una coda di attività, utilizza i metodi asincroni forniti dalla classe Queue e da un oggetto RPC. Chiama get_result() sull'oggetto RPC restituito per forzare il completamento della richiesta. Quando aggiungi attività in modo asincrono in una transazione, devi chiamare get_result() sull'oggetto RPC prima di eseguire il commit della transazione per assicurarti che la richiesta sia stata completata.

Accodamento delle attività nelle transazioni di Cloud Datastore

Puoi mettere in coda un'attività nell'ambito di una transazione di Datastore, in modo che venga messa in coda solo (e sia garantito che venga messa in coda) se la transazione viene eseguita correttamente. Attività aggiunte in un transazione sono ne viene considerata una parte e hanno lo stesso livello isolamento e coerenza.

Un'applicazione non può inserire più di cinque attività di transazione nelle code di lavoro durante una singola transazione. Le attività di transazione non devono avere nomi specificati dall'utente.

Il seguente esempio di codice mostra come inserire attività transazionali in un Esegui coda in modalità push come parte di una transazione Datastore:

from google.appengine.api import taskqueue
from google.appengine.ext import ndb

@ndb.transactional
def do_something_in_transaction():
  taskqueue.add(url='/path/to/my/worker', transactional=True)
  #...

do_something_in_transaction()

Utilizzo della libreria di attività differite anziché di un servizio worker

L'impostazione di un gestore per ogni singola attività (come descritto sezioni) possono essere complicate, così come la serializzazione e la deserializzazione argomenti adatti all'attività, soprattutto se si svolgono molte attività diverse ma piccole che vuoi eseguire in coda. L'SDK Python include una libreria (google.appengine.ext.deferred) che espone una semplice funzione che ti consente di aggirare tutto il lavoro di configurazione di gestori di attività dedicati e di serializzazione e deserializzazione dei parametri.

Per usare questa libreria, devi aggiungere l'deferred integrata a app.yaml. Per maggiori informazioni, consulta la sezione Gestori integrati della documentazione di riferimento app.yaml.

Per utilizzare la libreria deferred, è sufficiente passare la funzione e i suoi argomenti a deferred.defer():

import logging

from google.appengine.ext import deferred

def do_something_expensive(a, b, c=None):
    logging.info("Doing something expensive!")
    # Do your work here

# Somewhere else
deferred.defer(do_something_expensive, "Hello, world!", 42, True)

La libreria deferred pacchettizza la chiamata alla funzione e i relativi argomenti, quindi li aggiunge alla coda di attività. Quando l'attività viene eseguita, la libreria deferred esegue do_something_expensive("Hello, world!", 42, True).

Lavorare con le attività in un'applicazione multi-tenant

Per impostazione predefinita, le code in modalità push utilizzano lo spazio dei nomi attuale impostato nello spazio dei nomi nel momento in cui viene creata l'attività. Se la tua applicazione utilizza la multitenancy, consulta l'API Namespaces Python 2.

Passaggi successivi