Restore live autonomy with direct runtime and fresh snapshot capacity
This commit is contained in:
@@ -93,12 +93,20 @@ function rows(sql){
|
||||
}
|
||||
|
||||
async function deliverEvents(){
|
||||
// Reserve capacity for current snapshots so historical events cannot starve
|
||||
// live decisions. The remaining slots continue draining history in order.
|
||||
const fresh=rows(`SELECT id,HEX(kind),HEX(payload)
|
||||
FROM acore_auth.azerothai_event_outbox
|
||||
WHERE delivered_at IS NULL AND kind='player.snapshot'
|
||||
AND created_at >= NOW() - INTERVAL 90 SECOND
|
||||
ORDER BY id ASC LIMIT ${Math.max(1,Math.floor(EVENT_BATCH/2))}`);
|
||||
const batch=rows(`SELECT id,HEX(kind),HEX(payload)
|
||||
FROM acore_auth.azerothai_event_outbox
|
||||
WHERE delivered_at IS NULL
|
||||
ORDER BY CASE WHEN kind IN ('player.whisper','player.chat') THEN 0 ELSE 1 END, id
|
||||
LIMIT ${EVENT_BATCH}`);
|
||||
for(const [id,kindHex,payloadHex] of batch){
|
||||
${fresh.length?`AND id NOT IN (${fresh.map(row=>Number(row[0])).join(',')})`:''}
|
||||
ORDER BY CASE WHEN kind IN ('player.whisper','player.chat') AND created_at >= NOW() - INTERVAL 90 SECOND THEN 0 ELSE 1 END, id
|
||||
LIMIT ${Math.max(1,EVENT_BATCH-fresh.length)}`);
|
||||
for(const [id,kindHex,payloadHex] of [...fresh,...batch]){
|
||||
const kind=Buffer.from(kindHex||'','hex').toString('utf8');
|
||||
const payloadText=Buffer.from(payloadHex||'','hex').toString('utf8');
|
||||
let payload;
|
||||
@@ -116,7 +124,7 @@ async function deliverEvents(){
|
||||
mysql(`UPDATE acore_auth.azerothai_event_outbox SET delivered_at=NOW(6) WHERE id=${Number(id)}`);
|
||||
if(EVENT_GAP_MS)await sleep(EVENT_GAP_MS);
|
||||
}
|
||||
return batch.length;
|
||||
return fresh.length+batch.length;
|
||||
}
|
||||
|
||||
async function deliverResults(){
|
||||
@@ -136,6 +144,14 @@ async function deliverResults(){
|
||||
|
||||
function cleanup(){
|
||||
mysql(`
|
||||
CREATE TABLE IF NOT EXISTS acore_auth.azerothai_snapshot_archive LIKE acore_auth.azerothai_event_outbox;
|
||||
INSERT IGNORE INTO acore_auth.azerothai_snapshot_archive
|
||||
SELECT * FROM acore_auth.azerothai_event_outbox
|
||||
WHERE delivered_at IS NULL AND kind='player.snapshot'
|
||||
AND created_at < NOW() - INTERVAL 90 SECOND;
|
||||
UPDATE acore_auth.azerothai_event_outbox e
|
||||
JOIN acore_auth.azerothai_snapshot_archive a ON a.id=e.id
|
||||
SET e.delivered_at=NOW(6) WHERE e.delivered_at IS NULL;
|
||||
UPDATE acore_auth.azerothai_event_outbox
|
||||
SET delivered_at=NOW(6)
|
||||
WHERE delivered_at IS NULL
|
||||
@@ -151,10 +167,10 @@ console.log(`AzerothAI ALE DB relay started: ${BASE}, poll ${POLL_MS}ms`);
|
||||
|
||||
while(!stopping){
|
||||
try{
|
||||
if(Date.now()-lastCleanup>60_000){cleanup();lastCleanup=Date.now();}
|
||||
await deliverEvents();
|
||||
await deliverResults();
|
||||
await pullCommand();
|
||||
if(Date.now()-lastCleanup>60_000){cleanup();lastCleanup=Date.now();}
|
||||
await sleep(POLL_MS);
|
||||
}catch(error){
|
||||
console.error(new Date().toISOString(),error instanceof Error?error.message:String(error));
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// Run the built worker without Wrangler's development proxy or file watcher.
|
||||
import './sites-env.mjs';
|
||||
import {createRequire} from 'node:module';
|
||||
import path from 'node:path';
|
||||
import {readdirSync} from 'node:fs';
|
||||
import {unstable_getMiniflareWorkerOptions} from 'wrangler';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const wranglerRequire = createRequire(require.resolve('wrangler'));
|
||||
const {Miniflare} = wranglerRequire('miniflare');
|
||||
const config = path.resolve('dist/server/wrangler.json');
|
||||
const {workerOptions, externalWorkers, main} = unstable_getMiniflareWorkerOptions(config);
|
||||
if (!main) throw new Error('Build the application before starting the local runtime');
|
||||
const root = path.dirname(main);
|
||||
const modules = readdirSync(root, {recursive: true})
|
||||
.filter(file => /\.(m?js)$/.test(file))
|
||||
.map(file => ({type: 'ESModule', path: path.join(root, file)}));
|
||||
modules.sort((a, b) => a.path === main ? -1 : b.path === main ? 1 : 0);
|
||||
const runtime = new Miniflare({
|
||||
host: process.env.RUNTIME_HOST || (process.argv.includes('--lan') ? '0.0.0.0' : '127.0.0.1'),
|
||||
port: Number(process.env.RUNTIME_PORT || 8787),
|
||||
d1Persist: path.resolve('.wrangler/state/v3/d1'),
|
||||
workers: [{...workerOptions, modules, modulesRoot: root}, ...externalWorkers],
|
||||
});
|
||||
console.log(`AzerothAI local runtime ready: ${await runtime.ready}`);
|
||||
for (const signal of ['SIGINT', 'SIGTERM']) {
|
||||
process.once(signal, async () => { await runtime.dispose(); process.exit(0); });
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import {spawnSync} from 'node:child_process';
|
||||
import {writeFileSync,mkdirSync} from 'node:fs';
|
||||
const result=spawnSync(process.execPath,['node_modules/typescript/bin/tsc','core/service.ts','core/seed.ts','core/ale.ts','core/conversation.ts','--types','@cloudflare/workers-types,node','--outDir','.test-build','--module','commonjs','--target','es2022','--moduleResolution','node','--esModuleInterop','--skipLibCheck','--strict'],{stdio:'inherit'});
|
||||
const result=spawnSync(process.execPath,['node_modules/typescript/bin/tsc','core/service.ts','core/seed.ts','core/ale.ts','core/conversation.ts','core/autonomy.ts','--types','@cloudflare/workers-types,node','--outDir','.test-build','--module','commonjs','--target','es2022','--moduleResolution','node','--esModuleInterop','--skipLibCheck','--strict'],{stdio:'inherit'});
|
||||
if(result.status)process.exit(result.status);
|
||||
mkdirSync('.test-build',{recursive:true});writeFileSync('.test-build/package.json','{"type":"commonjs"}');
|
||||
process.exit(spawnSync(process.execPath,['--test','tests/core.test.cjs','tests/hardcore.test.cjs','tests/living-world.test.cjs','tests/ale.test.cjs','tests/brains.test.cjs','tests/conversation.test.cjs'],{stdio:'inherit'}).status??1);
|
||||
process.exit(spawnSync(process.execPath,['--test','tests/core.test.cjs','tests/hardcore.test.cjs','tests/living-world.test.cjs','tests/ale.test.cjs','tests/brains.test.cjs','tests/conversation.test.cjs','tests/autonomy.test.cjs'],{stdio:'inherit'}).status??1);
|
||||
|
||||
Reference in New Issue
Block a user