Skip to content

Commit

Permalink
ベンチマークの結果(passed/failed)をレスポンスに含める (#28)
Browse files Browse the repository at this point in the history
* ✨ FinishedBenchmarkにresultを追加

* 🩹 Goのコード生成

* 🚧 フロントエンドのコード生成

* client の openapi 生成に preprocess 処理を嚙ませた

* fix(client): type-check

* add @types/bun

* 🔧 OpenAPIの生成を全部openapi-gen.tsに移動

---------

Co-authored-by: cp-20 <[email protected]>
  • Loading branch information
ikura-hamu and cp-20 authored Jan 12, 2025
1 parent b0c0d07 commit 2257d97
Show file tree
Hide file tree
Showing 12 changed files with 274 additions and 35 deletions.
Binary file modified client/bun.lockb
Binary file not shown.
8 changes: 5 additions & 3 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"lint:ci": "eslint .",
"format": "prettier --write src/",
"format:ci": "prettier --check src/",
"openapi": "openapi-typescript ../openapi/openapi.yml -o src/api/openapi.ts"
"openapi": "bun run scripts/openapi-gen.ts"
},
"dependencies": {
"@tanstack/vue-query": "^5.62.16",
Expand All @@ -25,6 +25,7 @@
"devDependencies": {
"@iconify/vue": "^4.3.0",
"@tsconfig/node22": "^22.0.0",
"@types/bun": "^1.1.16",
"@types/node": "^22.9.3",
"@vitejs/plugin-vue": "^5.2.1",
"@vue/eslint-config-prettier": "^10.1.0",
Expand All @@ -39,11 +40,12 @@
"typescript": "~5.6.3",
"vite": "^6.0.1",
"vite-plugin-vue-devtools": "^7.6.5",
"vue-tsc": "^2.1.10"
"vue-tsc": "^2.1.10",
"yaml": "^2.7.0"
},
"msw": {
"workerDirectory": [
"public"
]
}
}
}
39 changes: 39 additions & 0 deletions client/scripts/openapi-gen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as Bun from 'bun'
import * as yaml from 'yaml'

import openapiTS, { astToString } from 'openapi-typescript'

// openapi-typescript does not support the combination of oneOf and allOf.
// This is a workaround to strip the discriminator property from the schema.
// ref: https://openapi-ts.dev/advanced#use-oneof-by-itself

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const stripDiscriminator = (schema: any) => {
Object.entries(schema).forEach(([key, value]) => {
if (!(typeof value === 'object')) return
if (key === 'discriminator') {
delete schema[key]
} else {
stripDiscriminator(value)
}
})
}

const file = await Bun.file('../openapi/openapi.yml').text()
const parsed = yaml.parse(file)
stripDiscriminator(parsed)
const temp = Bun.env['FILE'] ?? '/tmp/openapi.yml'
await Bun.write(temp, yaml.stringify(parsed))

const ast = await openapiTS(new URL(temp, import.meta.url).toString())
const contents = astToString(ast)

const contentsWithHeader =
`/**
* This file was auto-generated by openapi-typescript.
* Do not make direct changes to the file.
*/
` + contents

await Bun.write('./src/api/openapi.ts', contentsWithHeader)
2 changes: 2 additions & 0 deletions client/src/api/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,8 @@ export interface components {
/** @enum {string} */
status: 'finished'
score: components['schemas']['Score']
/** @enum {string} */
result: 'passed' | 'failed' | 'error'
createdAt: components['schemas']['CreatedAt']
startedAt: components['schemas']['StartedAt']
finishedAt: components['schemas']['FinishedAt']
Expand Down
32 changes: 22 additions & 10 deletions client/src/mock/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ const benchmarks: paths['/benchmarks/{benchmarkId}']['get']['responses']['200'][
score: 2000,
log: '',
adminLog: '',
result: 'passed',
},
{
id: '01943f68-7d22-7abb-8b13-0b727cd4597e',
Expand Down Expand Up @@ -148,6 +149,7 @@ const benchmarks: paths['/benchmarks/{benchmarkId}']['get']['responses']['200'][
score: 100,
log: '',
adminLog: '',
result: 'passed',
},
{
id: '01943f6e-69dd-7167-84b3-478cf9c3253d',
Expand All @@ -161,6 +163,7 @@ const benchmarks: paths['/benchmarks/{benchmarkId}']['get']['responses']['200'][
score: 1000,
log: '',
adminLog: '',
result: 'passed',
},
{
id: '01943f6e-8b29-79af-8430-7b06ae9307e5',
Expand All @@ -174,6 +177,7 @@ const benchmarks: paths['/benchmarks/{benchmarkId}']['get']['responses']['200'][
score: 1000,
log: '',
adminLog: '',
result: 'passed',
},
]

Expand Down Expand Up @@ -328,23 +332,31 @@ setInterval(() => {
// running のまま 60 秒経過したら finished にする
for (const b of runningBenchmarks) {
if (new Date(b.startedAt).getTime() + 60 * 1000 < Date.now()) {
// @ts-expect-error running -> finished で型の変換を行う必要があるが無視
b.status = 'finished'
// @ts-expect-error running -> finished で型の変換を行う必要があるが無視
b.finishedAt = new Date().toISOString()
const index = benchmarks.findIndex((bb) => bb.id === b.id)
const result = ['passed', 'failed', 'error'][Math.floor(Math.random() * 3)] as
| 'passed'
| 'failed'
| 'error'
benchmarks[index] = {
...b,
status: 'finished',
finishedAt: new Date().toISOString(),
result,
}
}
}

// 実行中のベンチマークがなくなったら、waiting のベンチマークを1つ running にする
if (runningBenchmarks.length === 0) {
const waitingBenchmark = benchmarks.find((b) => b.status === 'waiting')
if (waitingBenchmark !== undefined) {
// @ts-expect-error waiting -> running で型の変換を行う必要があるが無視
waitingBenchmark.status = 'running'
// @ts-expect-error waiting -> running で型の変換を行う必要があるが無視
waitingBenchmark.startedAt = new Date().toISOString()
// @ts-expect-error waiting -> running で型の変換を行う必要があるが無視
waitingBenchmark.score = 0
const index = benchmarks.findIndex((b) => b.id === waitingBenchmark.id)
benchmarks[index] = {
...waitingBenchmark,
status: 'running',
startedAt: new Date().toISOString(),
score: 0,
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion client/tsconfig.app.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "tsconfig.script.json"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
Expand Down
9 changes: 3 additions & 6 deletions client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
{
"files": [],
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
}
{ "path": "./tsconfig.node.json" },
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.script.json" }
]
}
28 changes: 28 additions & 0 deletions client/tsconfig.script.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"include": ["scripts/**/*"],
"compilerOptions": {
// Enable latest features
"lib": ["ESNext"],
"target": "ESNext",
"module": "ESNext",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,

// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,

// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,

// Some stricter flags
"noUnusedLocals": true,
"noUnusedParameters": true,
"noPropertyAccessFromIndexSignature": true
}
}
21 changes: 14 additions & 7 deletions openapi/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -979,9 +979,9 @@ components:
- discriminator:
propertyName: status
oneOf:
- $ref: "#/components/schemas/WaitingBenchmark"
- $ref: "#/components/schemas/RunningBenchmark"
- $ref: "#/components/schemas/FinishedBenchmark"
- $ref: "#/components/schemas/WaitingBenchmark"
- $ref: "#/components/schemas/RunningBenchmark"
- $ref: "#/components/schemas/FinishedBenchmark"
- properties:
log:
type: "string"
Expand All @@ -997,9 +997,9 @@ components:
- discriminator:
propertyName: status
oneOf:
- $ref: "#/components/schemas/WaitingBenchmark"
- $ref: "#/components/schemas/RunningBenchmark"
- $ref: "#/components/schemas/FinishedBenchmark"
- $ref: "#/components/schemas/WaitingBenchmark"
- $ref: "#/components/schemas/RunningBenchmark"
- $ref: "#/components/schemas/FinishedBenchmark"
- properties:
log:
type: "string"
Expand All @@ -1012,7 +1012,7 @@ components:
required:
- log
- adminLog

WaitingBenchmark:
type: "object"
description: "status=waiting のベンチマーク結果"
Expand Down Expand Up @@ -1089,6 +1089,12 @@ components:
- "finished"
score:
$ref: "#/components/schemas/Score"
result:
type: "string"
enum:
- "passed"
- "failed"
- "error"
createdAt:
$ref: "#/components/schemas/CreatedAt"
startedAt:
Expand All @@ -1102,6 +1108,7 @@ components:
- userId
- status
- score
- result
- createdAt
- startedAt
- finishedAt
Expand Down
Loading

0 comments on commit 2257d97

Please sign in to comment.