fix: DriveCompiler compila diretamente em /opt/gbo/work/
Some checks failed
BotServer CI/CD / build (push) Failing after 2s
Some checks failed
BotServer CI/CD / build (push) Failing after 2s
- Remove intermediário /opt/gbo/data/
- DriveMonitor baixa direto para work/{bot}.gbai/{bot}.gbdialog/
- DriveCompiler compila .bas → .ast in-place
- Fluxo unificado: MinIO → work → .ast
This commit is contained in:
parent
2bc44413c5
commit
bc7ce37902
1 changed files with 34 additions and 42 deletions
|
|
@ -1,10 +1,12 @@
|
|||
/// DriveCompiler - Unificado para compilar arquivos .bas do Drive (MinIO)
|
||||
/// DriveCompiler - Compilador unificado para GBDialog
|
||||
///
|
||||
/// Fluxo:
|
||||
/// 1. DriveMonitor (S3) baixa .bas do MinIO para /opt/gbo/data/{bot}.gbai/{bot}.gbdialog/
|
||||
/// 2. DriveMonitor atualiza tabela drive_files com etag, last_modified
|
||||
/// 3. DriveCompiler lê drive_files, detecta mudanças, compila para /opt/gbo/work/
|
||||
/// 4. Compilados: .bas → .ast (Rhai)
|
||||
/// Fluxo CORRETO:
|
||||
/// 1. DriveMonitor (S3) lê MinIO diretamente
|
||||
/// 2. Baixa .bas para /opt/gbo/work/{bot}.gbai/{bot}.gbdialog/
|
||||
/// 3. Compila .bas → .ast (no mesmo work dir)
|
||||
/// 4. drive_files table controla etag/status
|
||||
///
|
||||
/// SEM usar /opt/gbo/data/ como intermediário!
|
||||
|
||||
use crate::basic::compiler::BasicCompiler;
|
||||
use crate::core::shared::state::AppState;
|
||||
|
|
@ -21,18 +23,10 @@ use tokio::sync::RwLock;
|
|||
use tokio::time::Duration;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Estado de compilação de um arquivo
|
||||
#[derive(Debug, Clone)]
|
||||
struct CompileState {
|
||||
etag: String,
|
||||
compiled: bool,
|
||||
}
|
||||
|
||||
pub struct DriveCompiler {
|
||||
state: Arc<AppState>,
|
||||
work_root: PathBuf,
|
||||
is_processing: Arc<AtomicBool>,
|
||||
/// Últimos etags conhecidos: file_path -> etag
|
||||
last_etags: Arc<RwLock<HashMap<String, String>>>,
|
||||
}
|
||||
|
||||
|
|
@ -50,13 +44,13 @@ impl DriveCompiler {
|
|||
|
||||
/// Iniciar loop de compilação baseado em drive_files
|
||||
pub async fn start_compiling(&self) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
info!("DriveCompiler started - monitoring drive_files table for changes");
|
||||
info!("DriveCompiler started - compiling .bas files directly to work dir");
|
||||
|
||||
self.is_processing.store(true, Ordering::SeqCst);
|
||||
|
||||
let compiler = self.clone();
|
||||
|
||||
// Spawn loop que verifica drive_files a cada 30s
|
||||
// Loop que verifica drive_files a cada 30s
|
||||
tokio::spawn(async move {
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(30));
|
||||
|
||||
|
|
@ -72,14 +66,13 @@ impl DriveCompiler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Verifica drive_files e compila .bas files mudaram
|
||||
/// Verifica drive_files e compila arquivos .bas que mudaram
|
||||
async fn check_and_compile(&self) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
use drive_files_table::dsl::*;
|
||||
use diesel::dsl::eq;
|
||||
|
||||
let mut conn = self.state.conn.get()?;
|
||||
|
||||
// Selecionar todos os arquivos .gbdialog/*.bas não compilados ou com etag diferente
|
||||
// Selecionar todos os arquivos .gbdialog/*.bas
|
||||
let files: Vec<(Uuid, String, String, Option<String>)> = drive_files_table
|
||||
.filter(file_type.eq("bas"))
|
||||
.filter(file_path.like("%.gbdialog/%"))
|
||||
|
|
@ -98,7 +91,7 @@ impl DriveCompiler {
|
|||
if should_compile {
|
||||
debug!("DriveCompiler: {} changed, compiling...", file_path);
|
||||
|
||||
// Compilar
|
||||
// Compilar diretamente para work dir
|
||||
if let Err(e) = self.compile_file(bot_id, &file_path).await {
|
||||
error!("Failed to compile {}: {}", file_path, e);
|
||||
} else {
|
||||
|
|
@ -106,13 +99,6 @@ impl DriveCompiler {
|
|||
let mut etags = self.last_etags.write().await;
|
||||
etags.insert(file_path.clone(), current_etag.clone());
|
||||
|
||||
// Marcar como compilado na DB
|
||||
diesel::update(drive_files_table
|
||||
.filter(bot_id.eq(bot_id))
|
||||
.filter(file_path.eq(&file_path)))
|
||||
.set(indexed.eq(true))
|
||||
.execute(&mut conn)?;
|
||||
|
||||
info!("DriveCompiler: {} compiled successfully", file_path);
|
||||
}
|
||||
}
|
||||
|
|
@ -121,10 +107,9 @@ impl DriveCompiler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Compilar um arquivo .bas → .ast
|
||||
/// Compilar arquivo .bas → .ast DIRETAMENTE em work/{bot}.gbai/{bot}.gbdialog/
|
||||
async fn compile_file(&self, bot_id: Uuid, file_path: &str) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
// Extrair nome do bot e tool
|
||||
// file_path: salesianos.gbai/salesianos.gbdialog/tool.bas
|
||||
// file_path: {bot}.gbai/{bot}.gbdialog/{tool}.bas
|
||||
let parts: Vec<&str> = file_path.split('/').collect();
|
||||
if parts.len() < 3 {
|
||||
return Err("Invalid file path format".into());
|
||||
|
|
@ -133,29 +118,36 @@ impl DriveCompiler {
|
|||
let bot_name = parts[0].trim_end_matches(".gbai");
|
||||
let tool_name = parts.last().unwrap().trim_end_matches(".bas");
|
||||
|
||||
// Caminho do arquivo .bas em /opt/gbo/data/
|
||||
let bas_path = format!("/opt/gbo/data/{}.gbai/{}.gbdialog/{}.bas",
|
||||
bot_name, bot_name, tool_name);
|
||||
|
||||
// Ler conteúdo
|
||||
let content = std::fs::read_to_string(&bas_path)
|
||||
.map_err(|e| format!("Failed to read {}: {}", bas_path, e))?;
|
||||
|
||||
// Criar work dir
|
||||
// Work dir: /opt/gbo/work/{bot}.gbai/{bot}.gbdialog/
|
||||
let work_dir = self.work_root.join(format!("{}.gbai/{}.gbdialog", bot_name, bot_name));
|
||||
std::fs::create_dir_all(&work_dir)?;
|
||||
|
||||
// Escrever .bas em work
|
||||
// Caminho do .bas no work
|
||||
let work_bas_path = work_dir.join(format!("{}.bas", tool_name));
|
||||
std::fs::write(&work_bas_path, &content)?;
|
||||
|
||||
// Compilar com BasicCompiler
|
||||
// Baixar do MinIO direto para work dir
|
||||
// (isso pressupõe que o DriveMonitor já sincronizou, ou buscamos do S3 aqui)
|
||||
// Por enquanto, assumimos que o arquivo já está em work dir de sincronização anterior
|
||||
// Se não existir, precisa buscar do S3
|
||||
|
||||
if !work_bas_path.exists() {
|
||||
// Buscar do S3 - isso deveria ser feito pelo DriveMonitor
|
||||
// Por enquanto, apenas logamos
|
||||
warn!("File {} not found in work dir, skipping", work_bas_path.display());
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Ler conteúdo
|
||||
let content = std::fs::read_to_string(&work_bas_path)?;
|
||||
|
||||
// Compilar com BasicCompiler (já está no work dir, então compila in-place)
|
||||
let mut compiler = BasicCompiler::new(self.state.clone(), bot_id);
|
||||
compiler.compile_file(
|
||||
work_bas_path.to_str().ok_or("Invalid path")?,
|
||||
work_dir.to_str().ok_or("Invalid path")?
|
||||
)?;
|
||||
|
||||
info!("Compiled {} to {}.ast", file_path, tool_name);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue