88import traceback
99import json
1010import logging
11- import uuid
1211import os
1312import timeit
1413from botocore .vendored .requests .packages import urllib3
14+ import multiprocessing
1515
1616from . import event
1717from . import context
3131EXITCODE_ERR = 1
3232
3333
34- def call (func , event , timeout , environment_variables = {}, arn_string = "" , version_name = "" , library = None ):
34+ class ContextFilter (logging .Filter ):
35+ def __init__ (self , context ):
36+ super (ContextFilter , self ).__init__ ()
37+ self .context = context
38+
39+ def filter (self , record ):
40+ record .aws_request_id = self .context .aws_request_id
41+ return True
42+
43+
44+ def call (func , event , context , environment_variables = {}):
3545 export_variables (environment_variables )
36- e = json .loads (event )
37- c = context .Context (timeout , arn_string , version_name )
38- if library is not None :
39- load_lib (library )
40- request_id = uuid .uuid4 ()
4146
42- return _runner (request_id , e , c , func )
47+ return _runner (func , event , context )
4348
4449
4550def run (args ):
4651 # set env vars if path to json file was given
4752 set_environment_variables (args .environment_variables )
4853
4954 e = event .read_event (args .event )
50- c = context .Context (args .timeout , args .arn_string , args .version_name )
55+ c = context .Context (
56+ args .timeout ,
57+ invoked_function_arn = args .arn_string ,
58+ function_version = args .version_name )
5159 if args .library is not None :
5260 load_lib (args .library )
53- request_id = uuid .uuid4 ()
54- func = load (request_id , args .file , args .function )
55-
56- (result , err_type ) = _runner (request_id , e , c , func )
61+ func = load (c .aws_request_id , args .file , args .function )
62+
63+ (result , err_type ) = _runner (func , e , c )
5764
5865 if err_type is not None :
5966 sys .exit (EXITCODE_ERR )
6067
6168
62- def _runner (request_id , event , context , func ):
69+ def _runner (func , event , context ):
6370 logger = logging .getLogger ()
64- result = None
6571
6672 logger .info ("Event: {}" .format (event ))
67-
68- logger .info ("START RequestId: {}" .format (request_id ))
69-
70- start_time = timeit .default_timer ()
71- result , err_type = execute (func , event , context )
72- end_time = timeit .default_timer ()
73-
74- logger .info ("END RequestId: {}" .format (request_id ))
75-
73+ logger .info ("START RequestId: {} Version: {}" .format (
74+ context .aws_request_id , context .function_version ))
75+
76+ queue = multiprocessing .Queue ()
77+ p = multiprocessing .Process (
78+ target = execute_in_process ,
79+ args = (queue , func , event , context ,))
80+ p .start ()
81+ (result , err_type , duration ) = queue .get ()
82+ p .join ()
83+
84+ logger .info ("END RequestId: {}" .format (context .aws_request_id ))
85+ duration = "{0:.2f} ms" .format (duration )
86+ logger .info ("REPORT RequestId: {}\t Duration: {}" .format (
87+ context .aws_request_id , duration ))
7688 if type (result ) is TimeoutException :
7789 logger .error ("RESULT:\n {}" .format (result ))
7890 else :
7991 logger .info ("RESULT:\n {}" .format (result ))
8092
81- duration = "{0:.2f} ms" .format ((end_time - start_time ) * 1000 )
82- logger .info ("REPORT RequestId: {}\t Duration: {}" .format (
83- request_id , duration ))
84-
8593 return (result , err_type )
8694
8795
@@ -104,9 +112,13 @@ def load(request_id, path, function_name):
104112def execute (func , event , context ):
105113 err_type = None
106114
115+ logger = logging .getLogger ()
116+ log_filter = ContextFilter (context )
117+ logger .addFilter (log_filter )
118+
107119 try :
108- with time_limit (context .timeout ):
109- result = func (event , context .activate ())
120+ with time_limit (context ._timeout_in_seconds ):
121+ result = func (event , context ._activate ())
110122 except TimeoutException as err :
111123 result = err
112124 err_type = ERR_TYPE_TIMEOUT
@@ -120,3 +132,12 @@ def execute(func, event, context):
120132 err_type = ERR_TYPE_EXCEPTION
121133
122134 return result , err_type
135+
136+
137+ def execute_in_process (queue , func , event , context ):
138+ start_time = timeit .default_timer ()
139+ result , err_type = execute (func , event , context )
140+ end_time = timeit .default_timer ()
141+ duration = (end_time - start_time ) * 1000
142+
143+ queue .put ((result , err_type , duration ))
0 commit comments