-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
62802fd
commit 650a6d0
Showing
48 changed files
with
1,212 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// core/decorator/config.js | ||
const ConfigManager = require('../feature/configManager'); | ||
|
||
function Config(configKey, defaultValue = null) { | ||
/** | ||
* Função decoradora para injetar um valor de configuração na função decorada. | ||
* | ||
* @param {string} configKey - Chave da configuração a ser injetada. | ||
* @param {*} [defaultValue=null] - Valor padrão a ser usado se a configuração não for encontrada. | ||
*/ | ||
return function (func) { | ||
return function (...args) { | ||
// Obtém o valor da configuração usando o ConfigManager | ||
const configManager = new ConfigManager(); // Supondo que seja um Singleton | ||
const configValue = configManager.getConfig(configKey, defaultValue); | ||
|
||
// Injeta o valor da configuração nos argumentos da função | ||
return func(configValue, ...args); | ||
}; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// src\core\decorator\multithread.js | ||
const MultithreadManager = require('../feature/multithreadManager'); | ||
|
||
function Thread(func) { | ||
/** | ||
* Proxy para o decorador @Thread do PyTRobot. | ||
* Cria uma nova thread (ou worker) para a função decorada. | ||
*/ | ||
const multithreadManager = new MultithreadManager(); | ||
|
||
return function (...args) { | ||
// A função decorada é passada para a execução da thread | ||
const thread = multithreadManager.newThread(() => func(...args)); | ||
return thread; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// src\core\decorator\sqs.js | ||
const SQSRegistry = require('../strategy/sqs/sqsRegistry'); | ||
|
||
function SQS(thread = false) { | ||
/** | ||
* Decorator que registra a classe como um worker SQS, com a opção | ||
* de executar em uma nova thread ou não. | ||
* | ||
* @param {boolean} thread - Indica se a task deve ser executada em uma thread separada. | ||
*/ | ||
return function (cls) { | ||
const taskName = `${cls.name}`; // Usamos apenas o nome da classe em JS | ||
const taskRegistry = new SQSRegistry(); // Obtém a instância do TaskRegistry (singleton) | ||
|
||
// Armazena a preferência de execução em thread como um atributo da classe | ||
cls.runInThread = thread; | ||
|
||
// Registra a task no TaskRegistry | ||
taskRegistry.register(taskName, cls); | ||
|
||
return cls; // Retorna a classe sem modificá-la | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// src\core\decorator\state.js | ||
const StateRegistry = require('../strategy/state/stateRegistry'); | ||
|
||
function State(nextStateOnSuccess = '_FinisherState', nextStateOnFailure = '_FinisherState') { | ||
/** | ||
* Decorator que registra a classe como um estado. | ||
* | ||
* @param {string} nextStateOnSuccess - Estado subsequente em caso de sucesso. | ||
* @param {string} nextStateOnFailure - Estado subsequente em caso de falha. | ||
*/ | ||
return function (cls) { | ||
const stateRegistry = new StateRegistry(); | ||
stateRegistry.register(cls, nextStateOnSuccess, nextStateOnFailure); | ||
return cls; | ||
}; | ||
} | ||
|
||
function First(cls) { | ||
/** | ||
* Decorator que define o estado inicial (primeiro estado). | ||
*/ | ||
const stateRegistry = new StateRegistry(); | ||
stateRegistry.firstStateName = cls.name; // Define o nome do primeiro estado | ||
return cls; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// core/decorator/subprocess.js | ||
const SubprocessManager = require('../feature/subprocessManager'); | ||
|
||
function Subprocess(command, captureOutput = true, captureError = true) { | ||
/** | ||
* Função para acessar o SubprocessManager diretamente e executar um subprocesso. | ||
* | ||
* @param {Array<string>} command - Lista de strings contendo o comando a ser executado. | ||
* @param {boolean} [captureOutput=true] - Indica se a saída padrão do subprocesso deve ser capturada. | ||
* @param {boolean} [captureError=true] - Indica se a saída de erro do subprocesso deve ser capturada. | ||
* @returns {Object} Resultado do subprocesso, conforme retornado pelo SubprocessManager. | ||
*/ | ||
const subprocessManager = new SubprocessManager(); | ||
return subprocessManager.executeSubprocess(command, captureOutput, captureError); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// src\core\index.js | ||
const path = require('path'); | ||
const fs = require('fs'); | ||
const importModule = require('import-module'); | ||
const ConfigManager = require('./feature/configManager'); | ||
const MultithreadManager = require('./feature/multithreadManager'); | ||
const { SQSStrategy, StateStrategy } = require('./strategy/sqs'); | ||
const Singleton = require('./singleton'); | ||
const LogManager = require('./utility/logManager'); | ||
|
||
class JsTRobot { | ||
constructor(directory) { | ||
if (!PyTRobot.instance) { | ||
this.directory = directory || process.argv[2]; | ||
this.logger = new LogManager().getLogger('PyTRobot'); | ||
this.strategies = []; | ||
this._initialize(); | ||
PyTRobot.instance = this; | ||
} | ||
return PyTRobot.instance; | ||
} | ||
|
||
_initialize() { | ||
this.loadConfig(); | ||
this.loadSrc(); | ||
this.multithreadManager = new MultithreadManager(); | ||
this._checkAndRegisterStrategies(); | ||
} | ||
|
||
loadConfig() { | ||
this.configManager = new ConfigManager(); | ||
this.configManager.loadConfig(this.directory); | ||
} | ||
|
||
loadSrc() { | ||
this.baseDirectory = this.directory; | ||
this.srcPath = path.join(this.directory, 'src'); | ||
require('app-module-path').addPath(this.srcPath); // Para adicionar o diretório ao caminho | ||
if (fs.existsSync(this.srcPath)) { | ||
this._importAllFiles(); | ||
} else { | ||
throw new Error("'src' directory not found."); | ||
} | ||
} | ||
|
||
_importAllFiles() { | ||
const files = fs.readdirSync(this.srcPath); | ||
files.forEach(file => { | ||
if (file.endsWith('.js') && file !== 'index.js') { | ||
try { | ||
importModule(path.join(this.srcPath, file)); | ||
} catch (error) { | ||
this.logger.error(`Error importing module ${file}: ${error}`); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
_checkAndRegisterStrategies() { | ||
const SQSRegistry = require('./strategy/sqs/sqsRegistry'); | ||
const StateRegistry = require('./strategy/state/stateRegistry'); | ||
|
||
const taskRegistry = new SQSRegistry(); | ||
const stateRegistry = new StateRegistry(); | ||
|
||
if (Object.keys(taskRegistry.getAll()).length > 0) { | ||
this.strategies.push(new SQSStrategy()); | ||
} | ||
if (Object.keys(stateRegistry.getAll()).length > 0) { | ||
this.strategies.push(new StateStrategy()); | ||
} | ||
|
||
if (this.strategies.length === 0) { | ||
throw new Error('Nenhuma estratégia registrada ou especificada na configuração.'); | ||
} | ||
} | ||
|
||
initializeApplication() { | ||
this.strategies.forEach(strategy => strategy.initialize()); | ||
} | ||
|
||
startApplication() { | ||
const config = this.configManager.getAllConfigs(); | ||
const strategyPriority = (config.strategy_priority || 'sqs').toLowerCase(); | ||
const startDelay = config.strategy_start_delay || 10; | ||
|
||
if (strategyPriority === 'sqs') { | ||
this.strategies.sort(strategy => strategy.constructor.name.toLowerCase() !== 'sqsstrategy'); | ||
} else if (strategyPriority === 'state') { | ||
this.strategies.sort(strategy => strategy.constructor.name.toLowerCase() !== 'statestrategy'); | ||
} | ||
|
||
this.strategies.forEach(strategy => { | ||
strategy.start(); | ||
if (startDelay > 0) { | ||
setTimeout(() => strategy.start(), startDelay * 1000); | ||
} | ||
}); | ||
|
||
this.monitorThreads(); | ||
} | ||
|
||
stopApplication() { | ||
this.strategies.forEach(strategy => strategy.stop()); | ||
} | ||
|
||
monitorThreads() { | ||
setInterval(() => { | ||
const activeThreads = this.multithreadManager.getNumberActiveThreads(); | ||
if (activeThreads === 0) { | ||
this.logger.info("No active threads, terminating the process..."); | ||
this.stopApplication(); | ||
process.exit(0); | ||
} | ||
}, 10000); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// src\core\main.js | ||
const JsTRobot = require('./index'); | ||
|
||
function entrypoint() { | ||
if (process.argv.length < 3) { | ||
console.error("Usage: node main.js <project_directory>"); | ||
process.exit(1); | ||
} | ||
|
||
const directory = process.argv[2]; | ||
|
||
// Inicializa o JsTRobot | ||
const jstrobot = new JsTRobot(directory); | ||
jstrobot.initializeApplication(); | ||
jstrobot.startApplication(); | ||
} | ||
|
||
if (require.main === module) { | ||
entrypoint(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// src/core/strategy/applicationStrategy.js | ||
const MultithreadManager = require('../feature/multithreadManager'); | ||
const SubprocessManager = require('../feature/subprocessManager'); | ||
|
||
class ApplicationStrategy { | ||
constructor() { | ||
if (this.constructor === ApplicationStrategy) { | ||
throw new Error("Abstract classes can't be instantiated."); | ||
} | ||
this.multithreadManager = new MultithreadManager(); | ||
this.subprocessManager = new SubprocessManager(); | ||
} | ||
|
||
initialize() { | ||
throw new Error('Method "initialize()" must be implemented.'); | ||
} | ||
|
||
start() { | ||
throw new Error('Method "start()" must be implemented.'); | ||
} | ||
|
||
stop() { | ||
throw new Error('Method "stop()" must be implemented.'); | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,7 @@ | ||
// src/core/strategy/index.js | ||
|
||
class Strategy { | ||
execute() { | ||
throw new Error('execute() must be implemented'); | ||
} | ||
} | ||
|
||
class ConcreteStrategyA extends Strategy { | ||
execute() { | ||
console.log('Executing Strategy A'); | ||
} | ||
} | ||
const BaseRegistry = require('./base_registry'); | ||
const ApplicationStrategy = require('./application_strategy'); | ||
|
||
module.exports = { | ||
Strategy, | ||
ConcreteStrategyA, | ||
}; | ||
BaseRegistry, | ||
ApplicationStrategy, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// src/core/strategy/sqs/base_task.js | ||
const LogManager = require('../../utility/log_manager'); // Assumindo que você tenha algo semelhante | ||
|
||
class BaseTask { | ||
constructor() { | ||
if (this.constructor === BaseTask) { | ||
throw new Error("Abstract classes can't be instantiated."); | ||
} | ||
this.logManager = new LogManager(); | ||
this.logger = this.logManager.getLogger('SQS'); | ||
} | ||
|
||
// Método principal chamado para rodar a task | ||
run(...args) { | ||
// Chama o método de entrada antes de executar a lógica principal | ||
this._onEntry(); | ||
this.execute(...args); | ||
} | ||
|
||
// Método privado que chama o método on_entry do usuário | ||
_onEntry() { | ||
this.onEntry(); | ||
} | ||
|
||
// Método abstrato para lógica de entrada | ||
onEntry() { | ||
throw new Error("Method 'onEntry()' must be implemented."); | ||
} | ||
|
||
// Método abstrato para lógica principal da task | ||
execute(...args) { | ||
throw new Error("Method 'execute()' must be implemented."); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// src\core\strategy\sqs\index.js | ||
|
||
const BaseTask = require('./baseTask'); | ||
const SQSManager = require('./manager'); | ||
const SQSMessage = require('./messageBuilder').SQSMessage; | ||
const SQSMessageBuilder = require('./messageBuilder').SQSMessageBuilder; | ||
const SQSRegistry = require('./sqsRegistry'); | ||
const SQSStrategy = require('./strategy'); | ||
|
||
module.exports = { | ||
BaseTask, | ||
SQSManager, | ||
SQSMessage, | ||
SQSMessageBuilder, | ||
SQSRegistry, | ||
SQSStrategy, | ||
}; |
Oops, something went wrong.