worker.ts 3.2 KB

import * as fs from 'fs'
const path = require('path')

//多线程情况下 需要重新初始化config配置 
require('../../config/index');

const job_handlers = new Map();

/**
 * 递归加载指定目录下所有 .js 文件
 * @param {string|string[]} dirPaths 要加载的目录路径(可以是字符串或数组)
 * @param {object} [options] 配置选项
 * @param {boolean} [options.ignoreNodeModules=true] 是否忽略 node_modules 目录
 * @param {RegExp|function} [options.filter] 自定义过滤条件
 * @returns {object} 包含所有加载模块的对象(以相对路径为键)
 */
function loadAllJSFiles(dirPaths, options: any = {}) {


  const {
    ignoreNodeModules = true,
    filter = null
  }: any = options;

  const loadedModules = {};

  // 统一处理为数组形式
  if (!Array.isArray(dirPaths)) {
    dirPaths = [dirPaths];
  }

  dirPaths.forEach(dirPath => {
    // 解析为绝对路径
    const absoluteDir = path.resolve(dirPath);

    // 递归读取目录
    function scanDirectory(currentDir, relativePath = '') {
      const files = fs.readdirSync(currentDir);

      files.forEach(file => {
        const fullPath = path.join(currentDir, file);
        const stat = fs.statSync(fullPath);
        const newRelativePath = path.join(relativePath, file);

        if (stat.isDirectory()) {
          // 跳过 node_modules 目录(如果配置了忽略)
          if (ignoreNodeModules && file === 'node_modules') {
            return;
          }
          // 递归扫描子目录
          scanDirectory(fullPath, newRelativePath);
        } else if (
          path.extname(file) === '.js' &&
          (!filter ||
            (typeof filter === 'function' && filter(fullPath)) ||
            (filter instanceof RegExp && filter.test(fullPath)))
        ) {
          try {
            // 加载模块并存储
            const module = require(fullPath);
            const moduleKey = newRelativePath.replace(/\.js$/, '');
            loadedModules[moduleKey] = module;
          } catch (err) {
            console.error(`加载模块失败: ${fullPath}`, err);
          }
        }
      });
    }

    scanDirectory(absoluteDir);
  });

  return loadedModules;
}

(() => {

  const modules = loadAllJSFiles(['./build/job'], {
    ignoreNodeModules: true,
    filter: (filePath) => !['build/job/index.js', 'build/job/worker.js'].find(item => filePath.includes(item))
  });


  console.log(`=============开始加载任务=============`)
  for (const key1 in modules) {
    var m = modules[key1];
    for (const key2 in m) {
      if (typeof m[key2] === 'function') {
        if (job_handlers.has(key2)) {
          console.log(key2 + '已存在')
          continue;
        }
        job_handlers.set(key2, m[key2])
        // console.log(key2)
      }
    }
  }
  console.log(`=============任务加载完毕 共${job_handlers.size}个=============`)

})()


module.exports = ({ name, args }) => {

  switch (name) {
    case 'get_task_list':
      return job_handlers;
    case 'get_task_keys':
      return Array.from(job_handlers.keys());
    default:
      break;
  }

  var func = job_handlers.get(name);
  if (!func) {
    throw new Error(`任务${name}不存在`)
  }

  return func(args)
}