Processar eventos
O Amazon ECS envia eventos pelo menos uma vez. Isso significa que você pode receber várias cópias de determinado evento. Além disso, os eventos não podem ser distribuídos para os ouvintes de evento na ordem em que os eventos ocorreram.
Para que os eventos sejam ordenados adequadamente, a seção detail
de cada evento contém uma propriedade version
. Sempre que um recurso muda de estado, essa version
é incrementada. Eventos duplicados têm a mesma version
no objeto detail
. Caso você esteja replicando o estado da tarefa e com o Eventbridge, poderá comparar a versão de um recurso relatado pelas APIs do Amazon ECS com a version
relatada no Eventbridge para o recurso para verificar se a versão na sequência de eventos é atual. Os eventos com um número de propriedade da versão mais alto devem ser tratados como ocorridos depois de eventos com números da versão mais baixos.
Exemplo: processar eventos em uma função do AWS Lambda
O exemplo a seguir mostra uma função do Lambda escrita em Python 3.9 que captura os eventos de alteração de estado da tarefa e os salva na tabela a seguir do Amazon DynamoDB:
-
ECSTaskState: armazena o estado mais recente de uma tarefa. A ID da tabela é o valor
taskArn
da tarefa.
import json import boto3 def lambda_handler(event, context): id_name = "" new_record = {} # For debugging so you can see raw event format. print('Here is the event:') print((json.dumps(event))) if event["source"] != "aws.ecs": raise ValueError("Function only supports input from events with a source type of: aws.ecs") # Switch on task/container events. table_name = "" if event["detail-type"] == "ECS Task State Change": table_name = "ECSTaskState" id_name = "taskArn" event_id = event["detail"]["taskArn"] else: raise ValueError("detail-type for event is not a supported type. Exiting without saving event.") new_record["cw_version"] = event["version"] new_record.update(event["detail"]) # "status" is a reserved word in DDB, but it appears in containerPort # state change messages. if "status" in event: new_record["current_status"] = event["status"] new_record.pop("status") # Look first to see if you have received a newer version of an event ID. # If the version is OLDER than what you have on file, do not process it. # Otherwise, update the associated record with this latest information. print("Looking for recent event with same ID...") dynamodb = boto3.resource("dynamodb", region_name="us-east-1") table = dynamodb.Table(table_name) saved_event = table.get_item( Key={ id_name : event_id } ) if "Item" in saved_event: # Compare events and reconcile. print(("EXISTING EVENT DETECTED: Id " + event_id + " - reconciling")) if saved_event["Item"]["version"] < event["detail"]["version"]: print("Received event is a more recent version than the stored event - updating") table.put_item( Item=new_record ) else: print("Received event is an older version than the stored event - ignoring") else: print(("Saving new event - ID " + event_id)) table.put_item( Item=new_record )