- Newest
- Most votes
- Most comments
Hey @Subhan,
You are not alone in wanting to solve this problem with something out of the box.
Option 1: EventBridge
The most immediate solution would be to see if there is any EventBridge event you could subscribe to, to clean up your Lex session automatically. This may be a tad difficult though. There may not be an associated EventBridge event, and if there is, it may not contain the necessary details to properly clean up your Lex session, without forcing you to maintain an external database for your clean up Lambda Function to reference.
Option 2: (most-probably) Manual Timer
Code-wise, my team needed similar functionality. We wanted to know if a Lambda Function was long running, though this technology can be applied to any sort of place code can be ran. It's implemented in Python, but the idea is the same across languages.
Here's the code (a tad formatted for your sake) that could get the job done, to do something when a time limit has been reached; in your case, instead of throwing an error, you could clean up your Lex session:
from signal import signal, SIGALRM, alarm
from functools import wraps
from datetime import datetime
from pytz import timezone
DEFAULT_LIMIT_IN_MINUTES = 14
DEFAULT_LIMIT_IN_SECONDS = DEFAULT_LIMIT_IN_MINUTES * 60
def now(code='<time zone code here>') -> datetime:
return datetime.now(timezone(code))
def time_limit(start_time, limit_in_seconds=DEFAULT_LIMIT_IN_SECONDS):
"""
- Enforces a time limit, in seconds, to a function (default of {DEFAULT_LIMIT_IN_SECONDS} seconds).
- If the time limit is hit, an `Exception` is thrown.
- If the time limit isn't hit, the return value of the wrapped function is maintained.
Example Usage:
from datetime import datetime
from pytz import timezone
start_time = datetime.now(timezone('<time zone code here>'))
limit_in_seconds = 30
@time_limit(start_time, limit_in_seconds)
def process(record):
print(f'Processing {record}...')
sleep(60)
records = [
'a', # Will be cut off at the limit, 30 seconds, with an exception.
'b', # Will be cut off right away.
'c' # Will be cut off right away.
]
for record in records:
process(record)
:param start_time: The start time the limit should be compared against (e.g. Lambda Function start time to be shared across records of an invocation).
:param limit_in_seconds: The limit in seconds when the function should be stopped (default of {DEFAULT_LIMIT_IN_SECONDS} seconds).
:return: The return value of the wrapped function, if the time limit isn't hit.
"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
def throw():
raise Exception(f'Exceeded time limit of {limit_in_seconds} seconds.')
# When the time limit is hit, the signal calls this function.
def handler(_, __):
throw()
# Skips the signaling if the time limit was already hit in a previous invocation.
elapsed_seconds = int((now() - start_time).total_seconds())
seconds_remaining = limit_in_seconds - elapsed_seconds
if seconds_remaining <= 0:
throw()
signal(SIGALRM, handler)
alarm(seconds_remaining)
try:
result = func(*args, **kwargs)
finally:
cancel = 0
alarm(cancel)
return result
return wrapper
return decorator
I hope this helps. Let me know if you need any more assistance, Chase
Relevant content
- Accepted Answerasked a year ago
- AWS OFFICIALUpdated 4 months ago
- AWS OFFICIALUpdated 3 years ago
- AWS OFFICIALUpdated 2 months ago