33Licensed under MIT.
44'''
55
6- import imp
76import sys
87import traceback
98import json
@@ -39,10 +38,32 @@ def filter(self, record):
3938 return True
4039
4140
41+ class FunctionLoader ():
42+ def __init__ (self ,
43+ request_id = None ,
44+ source = None ,
45+ function_name = None ,
46+ library_path = None ,
47+ func = None ):
48+ self .request_id = request_id
49+ self .source = source
50+ self .function_name = function_name
51+ self .library_path = library_path
52+
53+ self .func = func
54+
55+ def load (self ):
56+ if self .library_path is not None :
57+ load_lib (self .library_path )
58+
59+ self .func = load_source (
60+ self .request_id , self .source , self .function_name )
61+
62+
4263def call (func , event , context , environment_variables = {}):
4364 export_variables (environment_variables )
44-
45- return _runner (func , event , context )
65+ loader = FunctionLoader ( func = func )
66+ return _runner (loader , event , context )
4667
4768
4869def run (args ):
@@ -54,17 +75,19 @@ def run(args):
5475 args .timeout ,
5576 invoked_function_arn = args .arn_string ,
5677 function_version = args .version_name )
57- if args .library is not None :
58- load_lib (args .library )
59- func = load (c .aws_request_id , args .file , args .function )
78+ loader = FunctionLoader (
79+ request_id = c .aws_request_id ,
80+ source = args .file ,
81+ function_name = args .function ,
82+ library_path = args .library )
6083
61- (result , err_type ) = _runner (func , e , c )
84+ (result , err_type ) = _runner (loader , e , c )
6285
6386 if err_type is not None :
6487 sys .exit (EXITCODE_ERR )
6588
6689
67- def _runner (func , event , context ):
90+ def _runner (loader , event , context ):
6891 logger = logging .getLogger ()
6992
7093 logger .info ("Event: {}" .format (event ))
@@ -74,7 +97,7 @@ def _runner(func, event, context):
7497 queue = multiprocessing .Queue ()
7598 p = multiprocessing .Process (
7699 target = execute_in_process ,
77- args = (queue , func , event , context ,))
100+ args = (queue , loader , event , context ,))
78101 p .start ()
79102 (result , err_type , duration ) = queue .get ()
80103 p .join ()
@@ -95,14 +118,25 @@ def load_lib(path):
95118 sys .path .append (os .path .abspath (path ))
96119
97120
98- def load (request_id , path , function_name ):
121+ def load_source (request_id , path , function_name ):
99122 mod_name = 'request-' + str (request_id )
100123
101124 file_path = os .path .abspath (path )
102125 file_directory = os .path .dirname (file_path )
103126 sys .path .append (file_directory )
104127
105- mod = imp .load_source (mod_name , path )
128+ if sys .version_info .major == 2 :
129+ import imp
130+ mod = imp .load_source (mod_name , path )
131+ elif sys .version_info .major == 3 and sys .version_info .minor >= 5 :
132+ import importlib
133+ spec = importlib .util .spec_from_file_location (mod_name , path )
134+ mod = importlib .util .module_from_spec (spec )
135+ sys .modules [mod_name ] = mod
136+ spec .loader .exec_module (mod )
137+ else :
138+ raise Exception ("unsupported python version" )
139+
106140 func = getattr (mod , function_name )
107141 return func
108142
@@ -132,9 +166,11 @@ def execute(func, event, context):
132166 return result , err_type
133167
134168
135- def execute_in_process (queue , func , event , context ):
169+ def execute_in_process (queue , loader , event , context ):
170+ if loader .func is None :
171+ loader .load ()
136172 start_time = timeit .default_timer ()
137- result , err_type = execute (func , event , context )
173+ result , err_type = execute (loader . func , event , context )
138174 end_time = timeit .default_timer ()
139175 duration = (end_time - start_time ) * 1000
140176
0 commit comments