Skip to content

Commit

Permalink
🧬 Experiment Citus over Redis for data persistance
Browse files Browse the repository at this point in the history
  • Loading branch information
ferdodo committed Dec 20, 2024
1 parent 40170ff commit 5d20538
Show file tree
Hide file tree
Showing 27 changed files with 2,243 additions and 261 deletions.
52 changes: 52 additions & 0 deletions back/entities/game.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { Playsig } from "core/types/playsig.js";
import type { PublicKey } from "core/types/public-key.js";
import type { Hero } from "core/types/hero.js";
import type { Appellation } from "core/types/appellation.js";
import type { Money } from "core/types/money.js";
import type { Level } from "core/types/level.js";
import type { Health } from "core/types/health.js";
import type { Combat } from "core/types/combat.js";
import type { Phase } from "core/types/phase.js";
import type { DateTime } from "core/types/date-time.js";
import { Entity, PrimaryKey, Property, Unique } from "@mikro-orm/core";

@Entity()
class Game {
@PrimaryKey()
playsig: Playsig;

@Property({ type: "json" })
publicKeys: PublicKey[];

@Property({ type: "json" })
nicknames: Record<PublicKey, string>;

@Property({ type: "json" })
playerHeroes: Record<PublicKey, Hero[]>;

@Property({ type: "json" })
playerBenches: Record<PublicKey, Record<number, Hero>>;

@Property({ type: "json" })
playerShops: Record<PublicKey, Appellation[]>;

@Property({ type: "json" })
playerMoney: Record<PublicKey, Money>;

@Property({ type: "json" })
playerLevel: Record<PublicKey, Level>;

@Property({ type: "json" })
playerHealths: Record<PublicKey, Health>;

@Property({ type: "json", nullable: true })
combats?: Combat[];

@Property()
phase: Phase;

@Property()
phaseStartAt: DateTime;
}

export const GameEntity = Game;
13 changes: 13 additions & 0 deletions back/entities/pool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Pool as PoolType } from "core/types/pool.js";
import { Entity, PrimaryKey, Property, Unique } from "@mikro-orm/core";

@Entity()
class Pool {
@PrimaryKey()
playsig: string;

@Property({ type: "json" })
heroes: PoolType["heroes"];
}

export const PoolEntity = Pool;
18 changes: 18 additions & 0 deletions back/entities/queuer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { PublicKey } from "core/types/public-key.js";
import type { Nickname } from "core/types/nickname.js";
import type { DateTime } from "core/types/date-time.js";
import { Entity, PrimaryKey, Property, Unique } from "@mikro-orm/core";

@Entity()
class Queuer {
@PrimaryKey()
publicKey: PublicKey;

@Property()
nickname: Nickname;

@Property()
createdAt: DateTime;
}

export const QueuerEntity = Queuer;
10 changes: 8 additions & 2 deletions back/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ import { createBackContext } from "./utils/create-back-context.js";
import { startServer } from "core/utils/start-server.js";
import { createRedisClient } from "./utils/create-redis-client.js";
import { createDataMapper } from "./utils/create-data-mapper.js";
import { MikroORM } from "@mikro-orm/postgresql";
import mikroOrmConfig from "./mikro-orm.config.js";

console.log("Server is starting...");

Promise.resolve()
.then(async () => {
const orm = await MikroORM.init(mikroOrmConfig);
const migrator = orm.getMigrator();
await migrator.up();
const redis = await createRedisClient();
const pubsub = await createRedisClient();
const backContext = await createBackContext(redis, pubsub);
const redisPub = await createRedisClient();
const dataMapper = await createDataMapper(orm, redis, redisPub);
const backContext = await createBackContext(dataMapper);
startServer(backContext);
console.log("\n╭───────────────────╮");
console.log("│ Autochess Backend |");
Expand Down
224 changes: 224 additions & 0 deletions back/migrations/.snapshot-autochess.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
{
"namespaces": ["public"],
"name": "public",
"tables": [
{
"columns": {
"playsig": {
"name": "playsig",
"type": "varchar(255)",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 255,
"mappedType": "string"
},
"public_keys": {
"name": "public_keys",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "json"
},
"nicknames": {
"name": "nicknames",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "json"
},
"player_heroes": {
"name": "player_heroes",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "json"
},
"player_benches": {
"name": "player_benches",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "json"
},
"player_shops": {
"name": "player_shops",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "json"
},
"player_money": {
"name": "player_money",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "json"
},
"player_level": {
"name": "player_level",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "json"
},
"player_healths": {
"name": "player_healths",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "json"
},
"combats": {
"name": "combats",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "json"
},
"phase": {
"name": "phase",
"type": "varchar(255)",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 255,
"mappedType": "string"
},
"phase_start_at": {
"name": "phase_start_at",
"type": "varchar(255)",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 255,
"mappedType": "string"
}
},
"name": "game",
"schema": "public",
"indexes": [
{
"keyName": "game_pkey",
"columnNames": ["playsig"],
"composite": false,
"constraint": true,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {},
"nativeEnums": {}
},
{
"columns": {
"playsig": {
"name": "playsig",
"type": "varchar(255)",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 255,
"mappedType": "string"
},
"heroes": {
"name": "heroes",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "json"
}
},
"name": "pool",
"schema": "public",
"indexes": [
{
"keyName": "pool_pkey",
"columnNames": ["playsig"],
"composite": false,
"constraint": true,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {},
"nativeEnums": {}
},
{
"columns": {
"public_key": {
"name": "public_key",
"type": "varchar(255)",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 255,
"mappedType": "string"
},
"nickname": {
"name": "nickname",
"type": "varchar(255)",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 255,
"mappedType": "string"
},
"created_at": {
"name": "created_at",
"type": "varchar(255)",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 255,
"mappedType": "string"
}
},
"name": "queuer",
"schema": "public",
"indexes": [
{
"keyName": "queuer_pkey",
"columnNames": ["public_key"],
"composite": false,
"constraint": true,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {},
"nativeEnums": {}
}
],
"nativeEnums": {}
}
17 changes: 17 additions & 0 deletions back/migrations/Migration20241220101918.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Migration } from "@mikro-orm/migrations";

export class Migration20241220101918 extends Migration {
override async up(): Promise<void> {
this.addSql(
`create table "game" ("playsig" varchar(255) not null, "public_keys" jsonb not null, "nicknames" jsonb not null, "player_heroes" jsonb not null, "player_benches" jsonb not null, "player_shops" jsonb not null, "player_money" jsonb not null, "player_level" jsonb not null, "player_healths" jsonb not null, "combats" jsonb null, "phase" varchar(255) not null, "phase_start_at" varchar(255) not null, constraint "game_pkey" primary key ("playsig"));`,
);

this.addSql(
`create table "pool" ("playsig" varchar(255) not null, "heroes" jsonb not null, constraint "pool_pkey" primary key ("playsig"));`,
);

this.addSql(
`create table "queuer" ("public_key" varchar(255) not null, "nickname" varchar(255) not null, "created_at" varchar(255) not null, constraint "queuer_pkey" primary key ("public_key"));`,
);
}
}
10 changes: 10 additions & 0 deletions back/migrations/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Migrations

This directory is automatically generated with MikroORM migration cli.

## How to create a new migrations ?

docker compose down -v
docker compose up -d --build back
docker compose exec back bun run migration:create
docker compose cp back:/autochess/back/migrations ./back/
20 changes: 20 additions & 0 deletions back/mikro-orm.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineConfig } from "@mikro-orm/postgresql";
import { GameEntity } from "./entities/game.js";
import { QueuerEntity } from "./entities/queuer.js";
import { PoolEntity } from "./entities/pool.js";
import { Migrator } from "@mikro-orm/migrations";

export default defineConfig({
entities: [GameEntity, QueuerEntity, PoolEntity],
extensions: [Migrator],
host: "citus",
dbName: process.env.MONGODB_DATABASE,
user: process.env.MONGODB_USERNAME,
password: process.env.MONGODB_PASSWORD,
migrations: {
tableName: "mikro_orm_migrations",
path: "./migrations",
transactional: true,
allOrNothing: true,
},
});
Loading

0 comments on commit 5d20538

Please sign in to comment.