def handler()

in Editor/Resources/CloudFormation/scenario4_spot_fleets/lambda/game_request.py [0:0]


def handler(event, context):
    """
    Handles requests to start games from the game client.
     This function records the game request from the client in the MatchmakingRequest table and enqueues the
     request in the SQS queue, which will then be used for matchmaking.
    :param event: lambda event, contains the region to player latency mapping in `regionToLatencyMapping` key, as well
     as the player information from the Cognito id tokens.
    :param context: lambda context, not used by this function
    :return:
     - 202 (Accepted) if the matchmaking request is accepted and is now being processed
     - 409 (Conflict) if the another matchmaking request is in progress
     - 500 (Internal Error) if error occurred when processing the matchmaking request
    """
    player_id = event["requestContext"]["authorizer"]["claims"]["sub"]
    start_time = round(time.time())
    print(f'Handling start game request. PlayerId: {player_id}, StartTime: {start_time}')

    region_to_latency_mapping = get_region_to_latency_mapping(event)
    if region_to_latency_mapping:
        print(f"Region to latency mapping: {region_to_latency_mapping}")
    else:
        print("No regionToLatencyMapping mapping provided")

    matchmaking_request_table_name = os.environ['MatchmakingRequestTableName']
    game_session_placement_table_name = os.environ['GameSessionPlacementTableName']
    simple_matchmaker_ticket_queue_url = os.environ['SimpleMatchMakerTicketQueueUrl']

    dynamodb = boto3.resource('dynamodb')
    matchmaking_request_table = dynamodb.Table(matchmaking_request_table_name)
    game_session_placement_table = dynamodb.Table(game_session_placement_table_name)

    sqs = boto3.resource('sqs')
    simple_matchmaker_ticket_queue = sqs.Queue(simple_matchmaker_ticket_queue_url)

    matchmaking_requests = matchmaking_request_table.query(
        KeyConditionExpression=Key('PlayerId').eq(player_id),
        ScanIndexForward=False
    )

    if matchmaking_requests['Count'] > 0 \
            and not is_matchmaking_request_terminal(matchmaking_requests['Items'][0], game_session_placement_table):
        # A existing matchmaking request in progress
        return {
            'headers': {
                'Content-Type': 'text/plain'
            },
            'statusCode': 409  # Conflict
        }

    matchmaking_request_table.put_item(
        Item={
            'PlayerId': player_id,
            'StartTime': start_time,
            'ExpirationTime': start_time + DEFAULT_TTL_IN_SECONDS,
            'Status': STATUS_PENDING
        }
    )

    message_attributes = {
        'PlayerId': {
            'StringValue': player_id,
            'DataType': 'String'
        },
        'StartTime': {
            'StringValue': str(start_time),
            'DataType': 'String'
        }
    }

    if region_to_latency_mapping:
        message_attributes["RegionToLatencyMapping"] = {
            'StringValue': json.dumps(region_to_latency_mapping),
            'DataType': 'String'
        }

    try:
        print('Sending message to matchmaking ticket queue')
        simple_matchmaker_ticket_queue.send_message(
            MessageBody=f"Matchmaking request ticket from PlayerId: {player_id} on StartTime: {start_time}",
            MessageAttributes=message_attributes,
            MessageDeduplicationId=player_id,
            MessageGroupId=SQS_QUEUE_GROUP_ID
        )
    except Exception as ex:
        print(f'Error occurred when sending message to matchmaking ticket queue. Exception: {ex}')
        print(f'Deleting matchmaking request for PlayerId: {player_id}, StartTime: {start_time}')
        matchmaking_request_table.delete_item(
            Key={
                'PlayerId': player_id,
                'StartTime': start_time
            }
        )
        return {
            # Error occurred when enqueuing matchmaking request
            'headers': {
                'Content-Type': 'text/plain'
            },
            'statusCode': 500
        }

    return {
        # Matchmaking request enqueued
        'headers': {
            'Content-Type': 'text/plain'
        },
        'statusCode': 202
    }