-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#64] Queue and Storage triggers for AWS, GCP and Azure #201
base: master
Are you sure you want to change the base?
Changes from 15 commits
4bd6f44
728288e
9c3a016
63ab522
94d3449
0f7454a
8f96eda
107b53f
ba67b4a
94a675a
bb0ade5
97d6345
be4e4f9
debbda0
3e52f3a
4bd7a20
a466aab
0b310c1
f8f3162
dac2840
7de164e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,12 +1,11 @@ | ||||||
|
||||||
import datetime, io, json, os, uuid | ||||||
import base64 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused import. The - import base64 Committable suggestion
Suggested change
ToolsRuff
|
||||||
import datetime, io, json, logging, os, uuid | ||||||
|
||||||
import azure.functions as func | ||||||
|
||||||
|
||||||
# TODO: usual trigger | ||||||
# implement support for blob and others | ||||||
def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse: | ||||||
def handler_http(req: func.HttpRequest, context: func.Context) -> func.HttpResponse: | ||||||
income_timestamp = datetime.datetime.now().timestamp() | ||||||
req_json = req.get_json() | ||||||
if 'connection_string' in req_json: | ||||||
|
@@ -73,3 +72,20 @@ def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse: | |||||
mimetype="application/json" | ||||||
) | ||||||
|
||||||
def handler_queue(msg: func.QueueMessage): | ||||||
logging.info('Python queue trigger function processed a queue item.') | ||||||
payload = msg.get_body().decode('utf-8') | ||||||
|
||||||
from . import function | ||||||
ret = function.handler(payload) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused variable The - ret = function.handler(payload) Committable suggestion
Suggested change
ToolsRuff
|
||||||
|
||||||
# TODO(oana) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are we missing something here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like this is missing the core part of making measurements and returning values. Maybe we can just do a bit of restructuring to have a single invocation + measurement code, called from three trigger interfaces? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just pushed the measurements infrastructure - all invocations are end-to-end complete. |
||||||
|
||||||
def handler_storage(blob: func.InputStream): | ||||||
logging.info('Python Blob trigger function processed %s', blob.name) | ||||||
payload = blob.readline().decode('utf-8') # TODO(oana) | ||||||
|
||||||
from . import function | ||||||
ret = function.handler(payload) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused variable The - ret = function.handler(payload) Committable suggestion
Suggested change
ToolsRuff
|
||||||
|
||||||
# TODO(oana) | ||||||
oanarosca marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,9 +1,10 @@ | ||||||
import datetime, io, json, os, uuid, sys | ||||||
import base64, datetime, io, json, os, uuid, sys | ||||||
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '.python_packages/lib/site-packages')) | ||||||
from google.cloud import storage as gcp_storage | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused import. The - from google.cloud import storage as gcp_storage Committable suggestion
Suggested change
ToolsRuff
|
||||||
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '.python_packages/lib/site-packages')) | ||||||
|
||||||
def handler(req): | ||||||
def handler_http(req): | ||||||
income_timestamp = datetime.datetime.now().timestamp() | ||||||
req_id = req.headers.get('Function-Execution-Id') | ||||||
|
||||||
|
@@ -62,3 +63,31 @@ def handler(req): | |||||
'cold_start_var': cold_start_var, | ||||||
'container_id': container_id, | ||||||
}), 200, {'ContentType': 'application/json'} | ||||||
|
||||||
def handler_queue(data, context): | ||||||
serialized_payload = data.get('data') | ||||||
payload = json.loads(base64.b64decode(serialized_payload).decode("utf-8")) | ||||||
|
||||||
from function import function | ||||||
ret = function.handler(payload) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused variable The - ret = function.handler(payload) Committable suggestion
Suggested change
ToolsRuff
|
||||||
|
||||||
# TODO(oana) | ||||||
oanarosca marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
def handler_storage(data, context): | ||||||
bucket_name = data.get('bucket') | ||||||
name = data.get('name') | ||||||
filepath = '/tmp/bucket_contents' | ||||||
|
||||||
from function import storage | ||||||
storage_inst = storage.storage.get_instance() | ||||||
storage_inst.download(bucket_name, name, filepath) | ||||||
|
||||||
payload = {} | ||||||
|
||||||
with open(filepath, 'r') as fp: | ||||||
payload = json.load(fp) | ||||||
|
||||||
from function import function | ||||||
ret = function.handler(payload) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused variable The - ret = function.handler(payload) Committable suggestion
Suggested change
ToolsRuff
|
||||||
|
||||||
# TODO(oana) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -303,6 +303,7 @@ Implement this step in the following function: | |
language_version: str, | ||
benchmark: str, | ||
is_cached: bool, | ||
trigger: Optional[Trigger.TriggerType], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Review the addition of the The addition of the Verify that all references to this function in the documentation and codebase have been updated to reflect this new parameter. Additionally, provide examples or scenarios where this parameter would be used, enhancing the understanding and applicability of this change. |
||
) -> Tuple[str, int] | ||
``` | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
azure-storage-blob==12.10.0 | ||
azure-storage-queue==12.9.0 | ||
azure-identity==1.16.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -132,6 +132,7 @@ def package_code( | |
language_version: str, | ||
benchmark: str, | ||
is_cached: bool, | ||
trigger: Optional[Trigger.TriggerType], | ||
) -> Tuple[str, int]: | ||
|
||
CONFIG_FILES = { | ||
|
@@ -258,13 +259,19 @@ def create_function(self, code_package: Benchmark, func_name: str) -> "LambdaFun | |
|
||
def cached_function(self, function: Function): | ||
|
||
from sebs.aws.triggers import LibraryTrigger | ||
from sebs.aws.triggers import LibraryTrigger, QueueTrigger, StorageTrigger | ||
|
||
for trigger in function.triggers(Trigger.TriggerType.LIBRARY): | ||
trigger.logging_handlers = self.logging_handlers | ||
cast(LibraryTrigger, trigger).deployment_client = self | ||
for trigger in function.triggers(Trigger.TriggerType.HTTP): | ||
trigger.logging_handlers = self.logging_handlers | ||
for trigger in function.triggers(Trigger.TriggerType.QUEUE): | ||
trigger.logging_handlers = self.logging_handlers | ||
cast(QueueTrigger, trigger).deployment_client = self | ||
for trigger in function.triggers(Trigger.TriggerType.STORAGE): | ||
trigger.logging_handlers = self.logging_handlers | ||
cast(StorageTrigger, trigger).deployment_client = self | ||
Comment on lines
+263
to
+275
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Review the handling of new trigger types in the The modifications to the Verify that the integration of these new triggers does not interfere with the existing functionalities of other trigger types. Additionally, ensure that the logging and deployment client settings are correctly applied to these triggers for consistent behavior across all trigger types. |
||
|
||
""" | ||
Update function code and configuration on AWS. | ||
|
@@ -484,10 +491,11 @@ def download_metrics( | |
) | ||
|
||
def create_trigger(self, func: Function, trigger_type: Trigger.TriggerType) -> Trigger: | ||
from sebs.aws.triggers import HTTPTrigger | ||
from sebs.aws.triggers import HTTPTrigger, QueueTrigger, StorageTrigger | ||
|
||
function = cast(LambdaFunction, func) | ||
|
||
trigger: Trigger | ||
if trigger_type == Trigger.TriggerType.HTTP: | ||
|
||
api_name = "{}-http-api".format(function.name) | ||
|
@@ -511,6 +519,14 @@ def create_trigger(self, func: Function, trigger_type: Trigger.TriggerType) -> T | |
elif trigger_type == Trigger.TriggerType.LIBRARY: | ||
# should already exist | ||
return func.triggers(Trigger.TriggerType.LIBRARY)[0] | ||
elif trigger_type == Trigger.TriggerType.QUEUE: | ||
trigger = QueueTrigger(func.name, self) | ||
trigger.logging_handlers = self.logging_handlers | ||
self.logging.info(f"Created Queue trigger for {func.name} function.") | ||
elif trigger_type == Trigger.TriggerType.STORAGE: | ||
trigger = StorageTrigger(func.name, self) | ||
trigger.logging_handlers = self.logging_handlers | ||
self.logging.info(f"Created Storage trigger for {func.name} function.") | ||
else: | ||
raise RuntimeError("Not supported!") | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One question here: are we certain we always receive a single event? do we need to add loop here?