mirror of
				https://kkgithub.com/actions/setup-python.git
				synced 2025-11-04 20:51:52 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			180 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
Object.defineProperty(exports, '__esModule', {
 | 
						|
  value: true
 | 
						|
});
 | 
						|
exports.default = void 0;
 | 
						|
 | 
						|
var _types = require('./types');
 | 
						|
 | 
						|
function _defineProperty(obj, key, value) {
 | 
						|
  if (key in obj) {
 | 
						|
    Object.defineProperty(obj, key, {
 | 
						|
      value: value,
 | 
						|
      enumerable: true,
 | 
						|
      configurable: true,
 | 
						|
      writable: true
 | 
						|
    });
 | 
						|
  } else {
 | 
						|
    obj[key] = value;
 | 
						|
  }
 | 
						|
  return obj;
 | 
						|
}
 | 
						|
 | 
						|
class Farm {
 | 
						|
  constructor(numOfWorkers, callback, computeWorkerKey) {
 | 
						|
    _defineProperty(this, '_computeWorkerKey', void 0);
 | 
						|
 | 
						|
    _defineProperty(this, '_cacheKeys', void 0);
 | 
						|
 | 
						|
    _defineProperty(this, '_callback', void 0);
 | 
						|
 | 
						|
    _defineProperty(this, '_last', void 0);
 | 
						|
 | 
						|
    _defineProperty(this, '_locks', void 0);
 | 
						|
 | 
						|
    _defineProperty(this, '_numOfWorkers', void 0);
 | 
						|
 | 
						|
    _defineProperty(this, '_offset', void 0);
 | 
						|
 | 
						|
    _defineProperty(this, '_queue', void 0);
 | 
						|
 | 
						|
    this._cacheKeys = Object.create(null);
 | 
						|
    this._callback = callback;
 | 
						|
    this._last = [];
 | 
						|
    this._locks = [];
 | 
						|
    this._numOfWorkers = numOfWorkers;
 | 
						|
    this._offset = 0;
 | 
						|
    this._queue = [];
 | 
						|
 | 
						|
    if (computeWorkerKey) {
 | 
						|
      this._computeWorkerKey = computeWorkerKey;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  doWork(method, ...args) {
 | 
						|
    return new Promise((resolve, reject) => {
 | 
						|
      const computeWorkerKey = this._computeWorkerKey;
 | 
						|
      const request = [_types.CHILD_MESSAGE_CALL, false, method, args];
 | 
						|
      let worker = null;
 | 
						|
      let hash = null;
 | 
						|
 | 
						|
      if (computeWorkerKey) {
 | 
						|
        hash = computeWorkerKey.call(this, method, ...args);
 | 
						|
        worker = hash == null ? null : this._cacheKeys[hash];
 | 
						|
      }
 | 
						|
 | 
						|
      const onStart = worker => {
 | 
						|
        if (hash != null) {
 | 
						|
          this._cacheKeys[hash] = worker;
 | 
						|
        }
 | 
						|
      };
 | 
						|
 | 
						|
      const onEnd = (error, result) => {
 | 
						|
        if (error) {
 | 
						|
          reject(error);
 | 
						|
        } else {
 | 
						|
          resolve(result);
 | 
						|
        }
 | 
						|
      };
 | 
						|
 | 
						|
      const task = {
 | 
						|
        onEnd,
 | 
						|
        onStart,
 | 
						|
        request
 | 
						|
      };
 | 
						|
 | 
						|
      if (worker) {
 | 
						|
        this._enqueue(task, worker.getWorkerId());
 | 
						|
      } else {
 | 
						|
        this._push(task);
 | 
						|
      }
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  _getNextTask(workerId) {
 | 
						|
    let queueHead = this._queue[workerId];
 | 
						|
 | 
						|
    while (queueHead && queueHead.task.request[1]) {
 | 
						|
      queueHead = queueHead.next || null;
 | 
						|
    }
 | 
						|
 | 
						|
    this._queue[workerId] = queueHead;
 | 
						|
    return queueHead && queueHead.task;
 | 
						|
  }
 | 
						|
 | 
						|
  _process(workerId) {
 | 
						|
    if (this._isLocked(workerId)) {
 | 
						|
      return this;
 | 
						|
    }
 | 
						|
 | 
						|
    const task = this._getNextTask(workerId);
 | 
						|
 | 
						|
    if (!task) {
 | 
						|
      return this;
 | 
						|
    }
 | 
						|
 | 
						|
    const onEnd = (error, result) => {
 | 
						|
      task.onEnd(error, result);
 | 
						|
 | 
						|
      this._unlock(workerId);
 | 
						|
 | 
						|
      this._process(workerId);
 | 
						|
    };
 | 
						|
 | 
						|
    task.request[1] = true;
 | 
						|
 | 
						|
    this._lock(workerId);
 | 
						|
 | 
						|
    this._callback(workerId, task.request, task.onStart, onEnd);
 | 
						|
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
 | 
						|
  _enqueue(task, workerId) {
 | 
						|
    const item = {
 | 
						|
      next: null,
 | 
						|
      task
 | 
						|
    };
 | 
						|
 | 
						|
    if (task.request[1]) {
 | 
						|
      return this;
 | 
						|
    }
 | 
						|
 | 
						|
    if (this._queue[workerId]) {
 | 
						|
      this._last[workerId].next = item;
 | 
						|
    } else {
 | 
						|
      this._queue[workerId] = item;
 | 
						|
    }
 | 
						|
 | 
						|
    this._last[workerId] = item;
 | 
						|
 | 
						|
    this._process(workerId);
 | 
						|
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
 | 
						|
  _push(task) {
 | 
						|
    for (let i = 0; i < this._numOfWorkers; i++) {
 | 
						|
      this._enqueue(task, (this._offset + i) % this._numOfWorkers);
 | 
						|
    }
 | 
						|
 | 
						|
    this._offset++;
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
 | 
						|
  _lock(workerId) {
 | 
						|
    this._locks[workerId] = true;
 | 
						|
  }
 | 
						|
 | 
						|
  _unlock(workerId) {
 | 
						|
    this._locks[workerId] = false;
 | 
						|
  }
 | 
						|
 | 
						|
  _isLocked(workerId) {
 | 
						|
    return this._locks[workerId];
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
exports.default = Farm;
 |