-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #85 from ant-xuexiao/feat/support-aws-sqs
feat: 增加 AWS SQS 消息队列功能
- Loading branch information
Showing
11 changed files
with
181 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import json | ||
import boto3 | ||
from botocore.exceptions import ClientError | ||
import logging | ||
|
||
from data_class import ExecuteMessage | ||
|
||
logger = logging.getLogger(__name__) | ||
sqs = boto3.resource("sqs") | ||
|
||
def get_queue(name): | ||
try: | ||
queue = sqs.get_queue_by_name(QueueName=name) | ||
except ClientError as error: | ||
logger.exception("Couldn't get queue named %s.", name) | ||
raise error | ||
else: | ||
return queue | ||
|
||
def send_message(queue, message: ExecuteMessage, message_attributes=None): | ||
if not message_attributes: | ||
message_attributes = { | ||
"type": { "StringValue": message.type, "DataType": "String" }, | ||
"repo": { "StringValue": message.repo, "DataType": "String" }, | ||
"path": { "StringValue": message.path, "DataType": "String" }, | ||
} | ||
|
||
message_body = encode_message(message=message) | ||
|
||
try: | ||
response = queue.send_message( | ||
MessageBody=message_body, MessageAttributes=message_attributes | ||
) | ||
|
||
except ClientError as error: | ||
logger.exception("Send message failed: %s", message_body) | ||
raise error | ||
else: | ||
return response | ||
|
||
async def receive_messages(queue, max_number = 10, wait_time = 2): | ||
try: | ||
messages = queue.receive_messages( | ||
MessageAttributeNames=["All"], | ||
MaxNumberOfMessages=max_number, | ||
WaitTimeSeconds=wait_time, | ||
) | ||
for msg in messages: | ||
logger.info("Received message: %s: %s", msg.message_id, msg.body) | ||
type, repo, path = unpack_message(msg) | ||
yield json.dumps({ "type": type, "repo": repo, "path": path }) | ||
delete_messages(queue, messages) | ||
|
||
except ClientError as error: | ||
logger.exception("Couldn't receive messages from queue: %s", queue) | ||
raise error | ||
|
||
|
||
def delete_messages(queue, messages): | ||
""" | ||
Delete a batch of messages from a queue in a single request. | ||
:param queue: The queue from which to delete the messages. | ||
:param messages: The list of messages to delete. | ||
:return: The response from SQS that contains the list of successful and failed | ||
message deletions. | ||
""" | ||
try: | ||
entries = [ | ||
{"Id": str(ind), "ReceiptHandle": msg.receipt_handle} | ||
for ind, msg in enumerate(messages) | ||
] | ||
response = queue.delete_messages(Entries=entries) | ||
if "Successful" in response: | ||
for msg_meta in response["Successful"]: | ||
logger.info("Deleted %s", messages[int(msg_meta["Id"])].receipt_handle) | ||
if "Failed" in response: | ||
for msg_meta in response["Failed"]: | ||
logger.warning( | ||
"Could not delete %s", messages[int(msg_meta["Id"])].receipt_handle | ||
) | ||
except ClientError: | ||
logger.exception("Couldn't delete messages from queue %s", queue) | ||
else: | ||
return response | ||
|
||
def encode_message(message: ExecuteMessage): | ||
return json.dumps({ | ||
"type": message.type, | ||
"repo": message.repo, | ||
"path": message.path, | ||
}) | ||
|
||
def unpack_message(msg): | ||
if (msg is None): | ||
return (f"", f"", f"") | ||
else: | ||
return ( | ||
msg.message_attributes["type"]["StringValue"], | ||
msg.message_attributes["repo"]["StringValue"], | ||
msg.message_attributes["path"]["StringValue"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,4 @@ PyGithub | |
python-multipart | ||
httpx[socks] | ||
load_dotenv | ||
boto3>=1.26.79 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
FROM public.ecr.aws/lambda/python:3.12 | ||
|
||
# Copy requirements.txt | ||
COPY requirements.txt ${LAMBDA_TASK_ROOT} | ||
|
||
# Install the specified packages | ||
RUN pip install -r requirements.txt | ||
|
||
# Copy function code | ||
COPY sqs_subscriber.py ${LAMBDA_TASK_ROOT} | ||
|
||
# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) | ||
CMD [ "sqs_subscriber.lambda_handler" ] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import json | ||
|
||
def lambda_handler(event, context): | ||
if event: | ||
batch_item_failures = [] | ||
sqs_batch_response = {} | ||
|
||
for record in event["Records"]: | ||
try: | ||
# process message | ||
print(f"receive message here") | ||
except Exception as e: | ||
batch_item_failures.append({"itemIdentifier": record['messageId']}) | ||
|
||
sqs_batch_response["batchItemFailures"] = batch_item_failures | ||
return sqs_batch_response |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters