Eine Funktion, die auf Neuigkeiten wartet
Ein Lambda-Handler ist eine Funktion, die ein Cloud-Dienst für Sie aufruft, wenn etwas geschieht, etwa wenn ein Foto in einem S3-Bucket landet. Die Neuigkeit kommt als Dictionary an, das Event heißt.
In diesem Modul schreiben Sie den Handler und testen ihn auf Ihrem eigenen Rechner. Nichts wird irgendwo bereitgestellt, und die Events denken Sie sich von Hand aus.
Am Ende dieser Lektion
Notiz
Ich kann einen Handler schreiben, der ein Event liest und ein Ergebnis zurückgibt.
Schlüsselwörter
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Handler | die Funktion, die der Dienst aufruft | handler(event, context) |
| Event | ein Dictionary, das beschreibt, was geschehen ist | |
| Record | ein Eintrag in der Liste der Neuigkeiten eines Events | |
| Fixture | ein ausgedachtes Event, das für Tests aufbewahrt wird | |
| Idempotent | zweimal ausgeführt ohne anderes Ergebnis |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Ein Handler nimmt ein Event und einen Context
Ein Handler ist eine gewöhnliche Python-Funktion mit zwei Parametern. event enthält die Neuigkeit. context enthält Angaben zur laufenden Funktion, etwa wie lange sie laufen darf.
Die Funktion gibt ein Ergebnis zurück. Weil sie nur eine Funktion ist, können Sie sie selbst mit einem ausgedachten Event aufrufen.
Nirgends bereitgestellt
Notiz
In diesem Modul wird keine Funktion hochgeladen. Die Event-Formen hier sind die dokumentierten, die eine Funktion erhält, keine Ausgabe eines Stacks von Ihnen. Sie testen, indem Sie die Funktion von Hand aufrufen.
Run: einen Handler von Hand aufrufen
event = {
"Records": [
{
"eventSource": "aws:s3",
"eventName": "ObjectCreated:Put",
"s3": {"bucket": {"name": "shop-uploads"}, "object": {"key": "bilder/katze.png", "size": 1024}},
}
]
}
def handler(event, context):
erster = event["Records"][0]
bucket = erster["s3"]["bucket"]["name"]
schluessel = erster["s3"]["object"]["key"]
return {"gespeichert": bucket + "/" + schluessel}
print(handler(event, None))
# Ändern Sie den Schlüssel in bilder/hund.png und führen Sie es noch einmal aus.
Ein Event enthält eine Liste von Records
Ein Event kann mehrere Records tragen, darum läuft ein Handler über Records. Jeder Record sagt in eventSource, woher er kommt.
Ein S3-Record nennt einen Bucket und einen Schlüssel. Ein SQS-Record, aus einer Warteschlange, hat einen body. Der Body ist ein String, ein JSON-Body braucht also json.loads, bevor Sie ihn lesen können.
Beispiel: zwei Arten von Record
| Feld | S3-Record | SQS-Record |
|---|---|---|
| eventSource | aws:s3 | aws:sqs |
| Was geschah | eventName, etwa ObjectCreated:Put | eine Nachricht im body |
| Wo man nachsieht | s3.bucket.name und s3.object.key | body, ein JSON-String |
| Eine eindeutige id | keine, auf die man sich verlassen kann | messageId |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Run: beide Arten von Record lesen
import json
event = {"Records": [
{"eventSource": "aws:sqs", "messageId": "m-1", "body": "{\"bestellung\": 1, \"artikel\": \"Tee\"}"},
{"eventSource": "aws:s3", "eventName": "ObjectCreated:Put",
"s3": {"bucket": {"name": "shop-uploads"}, "object": {"key": "logs/web.log"}}},
]}
def handler(event, context):
gesehen = []
for record in event["Records"]:
if record["eventSource"] == "aws:sqs":
bestellung = json.loads(record["body"])
gesehen.append("Bestellung " + str(bestellung["bestellung"]))
elif record["eventSource"] == "aws:s3":
gesehen.append("Datei " + record["s3"]["object"]["key"])
return gesehen
print(handler(event, None))
Ein Handler kann dieselbe Neuigkeit zweimal sehen
Eine Warteschlange verspricht At-least-once-Zustellung. Dieselbe Nachricht kann Ihre Funktion zweimal erreichen, etwa nach einem langsamen Lauf.
Ein Handler ist idempotent, wenn ein zweiter Lauf nichts ändert. Notieren Sie, was Sie erledigt haben, und überspringen Sie jede schon notierte Arbeit. Eine echte Funktion führt diese Notiz in einer Tabelle, und Lektion 9 benutzt eine. Hier steht eine Menge dafür.
Ein häufiger Fehler
Warnung
Viele denken, jede Nachricht komme nur einmal an. Das stimmt nicht: Die Zustellung ist mindestens einmal. Machen Sie den Handler sicher für einen zweiten Lauf, sonst wird eine Bestellung zweimal berechnet.
Run: Erledigtes überspringen
def bearbeiten(bestellungen, erledigt):
neu = []
for bestellung in bestellungen:
if bestellung in erledigt:
continue
erledigt.add(bestellung)
neu.append(bestellung)
return neu
erledigt = set()
print(bearbeiten([1, 2, 2], erledigt))
print(bearbeiten([2, 3], erledigt))
# Fügen Sie die Bestellung 4 zur zweiten Liste hinzu. Was gibt die zweite Zeile jetzt aus?