123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- #!-*-encoding:utf-8-*-
- """
- Faas 脚本定位函数
- """
- import pkgutil
- import operator
- import importlib
- import os
- import traceback
- from inspect import getmembers, isclass, isfunction
- import json
- # -------------------------------------配置-------------------------------------------------------
- handlerFileName = 'spider_result_handler'
- py_code_source_dir = os.environ.get('FAAS_CODE_DIR', 'F:/codes/python/clientSpider/')
- py_code_handler_path_list = [py_code_source_dir + handlerFileName]
- # 安全考虑,只能调用该目录下的方法,而不是任意模块方法,且作为 faas 服务内部约定,外部服务不需要感知该模块/目录名;但其目录下子目录/模块不做限制
- py_code_handler_module_prefix = handlerFileName + '.'
- # --------------------------------------约定------------------------------------------------------
- faas_function_name__support = 'support'
- faas_function_name__handle = 'handle'
- const_key_function_id = "faas__function-id"
- const_key_request_wrap = "faas__request_wrap"
- const_key_params = "faas__req.params"
- const_key_context = "faas__req.context"
- const_key_result = "faas__invoke_result"
- const_key_result_success = "faas__success"
- const_key_reload = "faas__reload"
- const_key_trace_id = "faas__trace_id"
- # --------------------------------------上下文------------------------------------------------------
- # 全局上下文(配置 稀缺连接)
- # 模块上下文(模块加载后存在的, 模块版本信息 )
- # 全局线程上下文(普通连接)
- # 线程任务上下文(任务 任务间传递信息 模块线程上下文)
- # --------------------------------------动态加载------------------------------------------------------
- loaded_functions_cache = {}
- # todo 进程锁
- def load_functions(force_reload_module):
- """
- 加载指定目录下的所有函数
- """
- func_dic = {}
- for importer, name, ispkg in pkgutil.walk_packages(py_code_handler_path_list, py_code_handler_module_prefix):
- if not ispkg and not operator.contains(name, 'test'):
- module = importlib.import_module(name)
- if force_reload_module:
- importlib.reload(module)
- # 遍历 module 中的元素, 取出所有的成员函数
- rest_dic = dict([(("%s-%s") % (name, func_name), value) for (func_name, value) in getmembers(module) if
- isfunction(value)])
- func_dic.update(rest_dic)
- global loaded_functions_cache
- loaded_functions_cache = func_dic
- # 函数路由
- def func_route(func_dic, func_name, args={}):
- """
- 函数路由: 根据函数名执行调用
- """
- # fixme 判断是否存在
- func = func_dic[func_name]
- print(func)
- if len(args) > 0:
- resp = func(**args)
- else:
- resp = func()
- return resp
- def handle(pycode_file_name, req):
- """
- handle a request to the function
- Args:
- pycode_file_name (str): python file
- req (str): request body
- :returns json
- """
- json_req = json.loads(req)
- support_func_name = py_code_handler_module_prefix + "%s-%s" % (pycode_file_name, faas_function_name__support)
- pycode_function_id = py_code_handler_module_prefix + "%s-%s" % (pycode_file_name, faas_function_name__handle)
- global loaded_functions_cache
- if const_key_reload in json_req:
- load_functions(True)
- # print("函数字典keys:{}".format(func_dic.keys()))
- # pycode_file_name = json_req[const_key_function_id] if const_key_function_id in json_req else None
- if not loaded_functions_cache.get(pycode_function_id):
- load_functions(True)
- args = json_req
- success = False
- result = None
- try:
- result = func_route(loaded_functions_cache, pycode_function_id, args)
- success = True
- print(pycode_function_id + ' SUCCESS')
- except Exception as e:
- print(pycode_function_id + ' Error: ' + traceback.format_exc())
- pass
- faas_resp = {
- const_key_result_success: success,
- const_key_context: json_req[const_key_request_wrap][const_key_context],
- const_key_function_id: pycode_function_id,
- const_key_result: result
- }
- #faas_resp = json.dumps(faas_resp)
- return faas_resp
- if __name__ == "__main__":
- """
- 测试handle
- """
- reqInfo = {
- const_key_request_wrap: {
- const_key_context: {"contextKey1": "k1", "contextKey2": "k2"},
- const_key_params: {"param1": "a", "param2": "b"}
- }
- }
- resp = handle("cat", json.dumps(reqInfo))
- print(resp)
|