feat: integrate RedisNode management into Project and Query services; enhance RedisNodeService with optimal node selection and connection options; update vm.constants to include RedisPlugin
This commit is contained in:
@ -1,4 +1,11 @@
|
||||
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
|
||||
import { Project } from "../../project/entities/project.entity";
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
ManyToMany,
|
||||
PrimaryGeneratedColumn,
|
||||
} from "typeorm";
|
||||
|
||||
@Entity("redisNode")
|
||||
export class RedisNode {
|
||||
@ -16,4 +23,8 @@ export class RedisNode {
|
||||
|
||||
@Column({ type: "varchar", length: 255 })
|
||||
password: string | null;
|
||||
|
||||
@ManyToMany(() => Project, (project) => project.redisNodes)
|
||||
@JoinColumn()
|
||||
projects: Project[];
|
||||
}
|
||||
|
||||
@ -4,9 +4,14 @@ import { RedisNode } from "./entities/redis.node.entity";
|
||||
import { RedisManagerController } from "./redis.manager.controller";
|
||||
import { RedisNodeService } from "./redisNode/redis.node.service";
|
||||
import { ApiModule } from "src/api/api.module";
|
||||
import { ProjectModule } from "src/project/project.module";
|
||||
|
||||
@Module({
|
||||
imports: [forwardRef(() => ApiModule), TypeOrmModule.forFeature([RedisNode])],
|
||||
imports: [
|
||||
forwardRef(() => ApiModule),
|
||||
forwardRef(() => ProjectModule),
|
||||
TypeOrmModule.forFeature([RedisNode]),
|
||||
],
|
||||
controllers: [RedisManagerController],
|
||||
providers: [RedisNodeService],
|
||||
exports: [RedisNodeService],
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { Inject, Injectable } from "@nestjs/common";
|
||||
import { InjectRepository } from "@nestjs/typeorm";
|
||||
import { RedisNode } from "../entities/redis.node.entity";
|
||||
import { Repository } from "typeorm";
|
||||
import { ProjectService } from "src/project/project.service";
|
||||
|
||||
@Injectable()
|
||||
export class RedisNodeService {
|
||||
constructor(
|
||||
@InjectRepository(RedisNode)
|
||||
private readonly redisNodeRepository: Repository<RedisNode>
|
||||
private readonly redisNodeRepository: Repository<RedisNode>,
|
||||
@Inject(ProjectService)
|
||||
private readonly projectService: ProjectService
|
||||
) {}
|
||||
|
||||
async create(
|
||||
@ -36,15 +39,55 @@ export class RedisNodeService {
|
||||
return this.redisNodeRepository.save(redisNode);
|
||||
}
|
||||
|
||||
async getConnectionOptions(id: string): Promise<{
|
||||
async findOptimalNode(): Promise<RedisNode | null> {
|
||||
const nodes = await this.redisNodeRepository.find({
|
||||
relations: ["projects"],
|
||||
});
|
||||
|
||||
if (nodes.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
nodes.sort((a, b) => a.projects.length - b.projects.length);
|
||||
|
||||
return nodes[0];
|
||||
}
|
||||
|
||||
async getConnectionOptions(projectId: string): Promise<{
|
||||
host: string;
|
||||
port: number;
|
||||
username: string;
|
||||
password: string;
|
||||
}> {
|
||||
const node = await this.redisNodeRepository.findOne({ where: { id } });
|
||||
const project = await this.projectService.findById(projectId);
|
||||
|
||||
if (!project) {
|
||||
throw new Error("Project not found");
|
||||
}
|
||||
|
||||
const node = project.redisNodes[0];
|
||||
if (!node) {
|
||||
throw new Error("Redis node not found");
|
||||
const newNode = await this.findOptimalNode();
|
||||
|
||||
if (!newNode) {
|
||||
throw new Error("No Redis nodes available");
|
||||
}
|
||||
|
||||
project.redisNodes.push(newNode);
|
||||
newNode.projects.push(project);
|
||||
await this.redisNodeRepository.save(newNode);
|
||||
|
||||
await this.projectService.updateRedisNode(
|
||||
project.id,
|
||||
project.redisNodes.map((n) => ({ id: n.id }))
|
||||
);
|
||||
|
||||
return {
|
||||
host: newNode.host,
|
||||
port: newNode.port,
|
||||
username: newNode.user,
|
||||
password: newNode.password,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user