feat: initialize Annual Gala Interactive System monorepo
- Set up pnpm workspace with 4 packages: shared, server, client-mobile, client-screen - Implement Redis atomic voting with Lua scripts (HINCRBY + distributed lock) - Add optimistic UI with IndexedDB queue for offline resilience - Configure Socket.io with auto-reconnection (infinite retries) - Separate mobile (Vant) and big screen (Pixi.js) dependencies Tech stack: - Frontend Mobile: Vue 3 + Vant + Socket.io-client - Frontend Screen: Vue 3 + Pixi.js + GSAP - Backend: Express + Socket.io + Redis + Prisma/MySQL Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
55
packages/server/src/index.ts
Normal file
55
packages/server/src/index.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { createServer } from 'http';
|
||||
import { app, logger } from './app';
|
||||
import { config } from './config';
|
||||
import { connectRedis } from './config/redis';
|
||||
import { initializeSocket } from './socket';
|
||||
import { loadLuaScripts } from './services/vote.service';
|
||||
|
||||
async function main(): Promise<void> {
|
||||
try {
|
||||
// Connect to Redis
|
||||
logger.info('Connecting to Redis...');
|
||||
await connectRedis();
|
||||
|
||||
// Load Lua scripts
|
||||
logger.info('Loading Lua scripts...');
|
||||
await loadLuaScripts();
|
||||
|
||||
// Create HTTP server
|
||||
const httpServer = createServer(app);
|
||||
|
||||
// Initialize Socket.io
|
||||
logger.info('Initializing Socket.io...');
|
||||
await initializeSocket(httpServer);
|
||||
|
||||
// Start server
|
||||
httpServer.listen(config.port, () => {
|
||||
logger.info({ port: config.port, env: config.nodeEnv }, 'Server started');
|
||||
logger.info(`Health check: http://localhost:${config.port}/health`);
|
||||
});
|
||||
|
||||
// Graceful shutdown
|
||||
const shutdown = async (signal: string) => {
|
||||
logger.info({ signal }, 'Shutdown signal received');
|
||||
|
||||
httpServer.close(() => {
|
||||
logger.info('HTTP server closed');
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
// Force exit after 10 seconds
|
||||
setTimeout(() => {
|
||||
logger.error('Forced shutdown after timeout');
|
||||
process.exit(1);
|
||||
}, 10000);
|
||||
};
|
||||
|
||||
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
||||
process.on('SIGINT', () => shutdown('SIGINT'));
|
||||
} catch (error) {
|
||||
logger.error({ error }, 'Failed to start server');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user