handleManager.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #!-*-encoding:utf-8-*-
  2. """
  3. Faas 脚本定位函数
  4. """
  5. import pkgutil
  6. import operator
  7. import importlib
  8. import os
  9. import traceback
  10. from inspect import getmembers, isclass, isfunction
  11. import json
  12. # -------------------------------------配置-------------------------------------------------------
  13. handlerFileName = 'spider_result_handler'
  14. py_code_source_dir = os.environ.get('FAAS_CODE_DIR', 'F:/codes/python/clientSpider/')
  15. py_code_handler_path_list = [py_code_source_dir + handlerFileName]
  16. # 安全考虑,只能调用该目录下的方法,而不是任意模块方法,且作为 faas 服务内部约定,外部服务不需要感知该模块/目录名;但其目录下子目录/模块不做限制
  17. py_code_handler_module_prefix = handlerFileName + '.'
  18. # --------------------------------------约定------------------------------------------------------
  19. faas_function_name__support = 'support'
  20. faas_function_name__handle = 'handle'
  21. const_key_function_id = "faas__function-id"
  22. const_key_request_wrap = "faas__request_wrap"
  23. const_key_params = "faas__req.params"
  24. const_key_context = "faas__req.context"
  25. const_key_result = "faas__invoke_result"
  26. const_key_result_success = "faas__success"
  27. const_key_reload = "faas__reload"
  28. const_key_trace_id = "faas__trace_id"
  29. # --------------------------------------上下文------------------------------------------------------
  30. # 全局上下文(配置 稀缺连接)
  31. # 模块上下文(模块加载后存在的, 模块版本信息 )
  32. # 全局线程上下文(普通连接)
  33. # 线程任务上下文(任务 任务间传递信息 模块线程上下文)
  34. # --------------------------------------动态加载------------------------------------------------------
  35. loaded_functions_cache = {}
  36. # todo 进程锁
  37. def load_functions(force_reload_module):
  38. """
  39. 加载指定目录下的所有函数
  40. """
  41. func_dic = {}
  42. for importer, name, ispkg in pkgutil.walk_packages(py_code_handler_path_list, py_code_handler_module_prefix):
  43. if not ispkg and not operator.contains(name, 'test'):
  44. module = importlib.import_module(name)
  45. if force_reload_module:
  46. importlib.reload(module)
  47. # 遍历 module 中的元素, 取出所有的成员函数
  48. rest_dic = dict([(("%s-%s") % (name, func_name), value) for (func_name, value) in getmembers(module) if
  49. isfunction(value)])
  50. func_dic.update(rest_dic)
  51. global loaded_functions_cache
  52. loaded_functions_cache = func_dic
  53. # 函数路由
  54. def func_route(func_dic, func_name, args={}):
  55. """
  56. 函数路由: 根据函数名执行调用
  57. """
  58. # fixme 判断是否存在
  59. func = func_dic[func_name]
  60. print(func)
  61. if len(args) > 0:
  62. resp = func(**args)
  63. else:
  64. resp = func()
  65. return resp
  66. def handle(pycode_file_name, req):
  67. """
  68. handle a request to the function
  69. Args:
  70. pycode_file_name (str): python file
  71. req (str): request body
  72. :returns json
  73. """
  74. json_req = json.loads(req)
  75. support_func_name = py_code_handler_module_prefix + "%s-%s" % (pycode_file_name, faas_function_name__support)
  76. pycode_function_id = py_code_handler_module_prefix + "%s-%s" % (pycode_file_name, faas_function_name__handle)
  77. global loaded_functions_cache
  78. if const_key_reload in json_req:
  79. load_functions(True)
  80. # print("函数字典keys:{}".format(func_dic.keys()))
  81. # pycode_file_name = json_req[const_key_function_id] if const_key_function_id in json_req else None
  82. if not loaded_functions_cache.get(pycode_function_id):
  83. load_functions(True)
  84. args = json_req
  85. success = False
  86. result = None
  87. try:
  88. result = func_route(loaded_functions_cache, pycode_function_id, args)
  89. success = True
  90. print(pycode_function_id + ' SUCCESS')
  91. except Exception as e:
  92. print(pycode_function_id + ' Error: ' + traceback.format_exc())
  93. pass
  94. faas_resp = {
  95. const_key_result_success: success,
  96. const_key_context: json_req[const_key_request_wrap][const_key_context],
  97. const_key_function_id: pycode_function_id,
  98. const_key_result: result
  99. }
  100. #faas_resp = json.dumps(faas_resp)
  101. return faas_resp
  102. if __name__ == "__main__":
  103. """
  104. 测试handle
  105. """
  106. reqInfo = {
  107. const_key_request_wrap: {
  108. const_key_context: {"contextKey1": "k1", "contextKey2": "k2"},
  109. const_key_params: {"param1": "a", "param2": "b"}
  110. }
  111. }
  112. resp = handle("cat", json.dumps(reqInfo))
  113. print(resp)