feat(core-edu): 完整实现 core-edu 教学核心服务
包含 classes/exams/homework/grades/attendance/scheduling 域、outbox、iam-consumer、redis 配置等完整实现
This commit is contained in:
@@ -2,6 +2,7 @@ import { NestFactory } from "@nestjs/core";
|
||||
import { AppModule } from "./app.module.js";
|
||||
import { env } from "./config/env.js";
|
||||
import { connectKafka, disconnectKafka } from "./config/kafka.js";
|
||||
import { connectRedis, disconnectRedis } from "./config/redis.js";
|
||||
import { outboxPublisher } from "./shared/outbox/outbox.publisher.js";
|
||||
import { GlobalErrorFilter } from "./shared/errors/global-error.filter.js";
|
||||
import { initTracer, shutdownTracer } from "./shared/observability/tracer.js";
|
||||
@@ -27,33 +28,33 @@ async function bootstrap(): Promise<void> {
|
||||
// publisher will retry sends and messages stay pending until Kafka recovers.
|
||||
void connectKafka();
|
||||
|
||||
// Connect Redis for distributed lock (homework submission idempotency).
|
||||
// Non-blocking: if Redis is unavailable, service still starts; lock-based
|
||||
// operations will fall back to DB unique index for idempotency.
|
||||
void connectRedis();
|
||||
|
||||
// Start the transactional outbox publisher - polls pending messages
|
||||
// and publishes them to Kafka topics defined in TOPIC_MAP.
|
||||
await outboxPublisher.start();
|
||||
|
||||
await app.listen(env.PORT);
|
||||
logger.info(
|
||||
{ port: env.PORT, service: "core-edu" },
|
||||
"CoreEdu service is listening",
|
||||
{ port: env.PORT, grpcPort: env.GRPC_PORT, service: "core-edu" },
|
||||
"CoreEdu service is listening (HTTP; gRPC port reserved for P3)",
|
||||
);
|
||||
|
||||
process.on("SIGTERM", async () => {
|
||||
logger.info("SIGTERM received, shutting down gracefully...");
|
||||
const shutdown = async (signal: string): Promise<void> => {
|
||||
logger.info({ signal }, "Shutting down gracefully...");
|
||||
await outboxPublisher.stop();
|
||||
await disconnectRedis();
|
||||
await disconnectKafka();
|
||||
await shutdownTracer();
|
||||
await app.close();
|
||||
process.exit(0);
|
||||
});
|
||||
};
|
||||
|
||||
process.on("SIGINT", async () => {
|
||||
logger.info("SIGINT received, shutting down gracefully...");
|
||||
await outboxPublisher.stop();
|
||||
await disconnectKafka();
|
||||
await shutdownTracer();
|
||||
await app.close();
|
||||
process.exit(0);
|
||||
});
|
||||
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
||||
process.on("SIGINT", () => void shutdown("SIGINT"));
|
||||
}
|
||||
|
||||
void bootstrap();
|
||||
|
||||
Reference in New Issue
Block a user