_discovery.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. """XXL-JOB handler 自动发现 —— pkgutil + importlib 扫描导入
  2. 扫描 supply.handlers 包下的所有非私有模块,逐一 import,
  3. 触发 @xxl_job 装饰器将 handler 注册到 _XXL_REGISTRY。
  4. """
  5. import importlib
  6. import logging
  7. import pkgutil
  8. logger = logging.getLogger(__name__)
  9. def discover_and_register(package: str = "supply.handlers") -> None:
  10. """自动发现并导入 package 下的所有 handler 模块
  11. 跳过 _ 前缀的私有模块和子包。每个模块被 import 时,
  12. @xxl_job 装饰器自动执行,将 handler 写入共享的 _XXL_REGISTRY。
  13. 幂等调用:importlib 使用 sys.modules 缓存,重复调用是 no-op。
  14. Args:
  15. package: 点分隔的 Python 包路径,默认 "supply.handlers"
  16. """
  17. try:
  18. pkg = importlib.import_module(package)
  19. except ImportError:
  20. logger.warning(
  21. "XXL-JOB handler 包 %r 不存在,无 handler 注册", package
  22. )
  23. return
  24. registered = 0
  25. for finder, name, is_pkg in pkgutil.iter_modules(
  26. pkg.__path__, pkg.__name__ + "."
  27. ):
  28. if name.split(".")[-1].startswith("_"):
  29. continue
  30. try:
  31. importlib.import_module(name)
  32. registered += 1
  33. logger.debug("XXL-JOB 发现 handler 模块: %s", name)
  34. except Exception:
  35. logger.exception("XXL-JOB handler 模块 %r 导入失败,跳过", name)
  36. if registered:
  37. logger.info(
  38. "XXL-JOB 自动发现完成: 已导入 %d 个 handler 模块", registered
  39. )
  40. else:
  41. logger.info("XXL-JOB 自动发现: 在 %r 中未找到 handler 模块", package)