From af19fd33fc2438c3bd08025b0f7cca2ef2356a82 Mon Sep 17 00:00:00 2001 From: Settel Date: Tue, 2 Aug 2022 23:34:30 +0200 Subject: [PATCH] feat: sync engine with server, handle errors (WIP) --- client/package.json | 3 +- client/src/composables/engine/callApi.ts | 14 ++++++ client/src/composables/engine/fetchUpdate.ts | 46 ++++++++++++++++++- client/src/composables/engine/startStop.ts | 10 ++-- client/src/composables/useEngine.ts | 15 +++--- client/src/stores/UserinfoStore.ts | 3 ++ client/yarn.lock | 5 ++ .../d06fb83a-51eb-477e-b57c-6138a38eecb5.json | 2 +- 8 files changed, 83 insertions(+), 15 deletions(-) create mode 100644 client/src/composables/engine/callApi.ts diff --git a/client/package.json b/client/package.json index c5e9058..802f449 100644 --- a/client/package.json +++ b/client/package.json @@ -15,6 +15,7 @@ "sass-loader": "^13.0.2" }, "dependencies": { - "@pinia/nuxt": "^0.3.1" + "@pinia/nuxt": "^0.3.1", + "build-url": "^6.0.1" } } diff --git a/client/src/composables/engine/callApi.ts b/client/src/composables/engine/callApi.ts new file mode 100644 index 0000000..d1f2af9 --- /dev/null +++ b/client/src/composables/engine/callApi.ts @@ -0,0 +1,14 @@ +import buildUrl from 'build-url' + +export type QueryParams = { + [name: string]: string +} + +export async function callApi(path: string, queryParams: QueryParams) { + const url = buildUrl('/', { + path, + queryParams, + }) + + return await $fetch(url) +} diff --git a/client/src/composables/engine/fetchUpdate.ts b/client/src/composables/engine/fetchUpdate.ts index 5e3893f..b003edf 100644 --- a/client/src/composables/engine/fetchUpdate.ts +++ b/client/src/composables/engine/fetchUpdate.ts @@ -1,3 +1,45 @@ -export function fetchUpdate() { - console.log('fetchUpdate() called') +import { useUserinfoStore } from "@/stores/UserinfoStore" + +export async function fetchUpdate() { + if (this.shouldStop || !this.isActive) { + this.isActive = false + this.shouldStop = false + console.debug('engine stopped') + return + } + + let delay = 0 + try { + console.log(`sync[${this.version}]`) + const userInfoStore = useUserinfoStore() + const response = await this.callApi('/api/sync', { + v: this.version + 1, + g: userInfoStore.gameId, + }) + + if (!Number.isInteger(response.version)) { + throw Error('unexpected response for sync, property version not found.') + } + + // TODO: parse answer + this.version = parseInt(response.version) + } catch (e) { + if (!e.response) { + // request aborted or other causes + return + } + + const { status, statusText } = e.response + if (status == 200) { + delay = 1000 + } else { + console.warn(`HTTP ${status} ${statusText}`) + delay = 5000 + this.version = -1 + } + } + + window.setTimeout(() => { + this.fetchUpdate() + }, delay) } \ No newline at end of file diff --git a/client/src/composables/engine/startStop.ts b/client/src/composables/engine/startStop.ts index 36ab499..402a1e1 100644 --- a/client/src/composables/engine/startStop.ts +++ b/client/src/composables/engine/startStop.ts @@ -1,7 +1,7 @@ import { useUserinfoStore } from "@/stores/UserinfoStore" export function start(): void { - if (this.isActive.value && !this.shouldStop.value) { + if (this.isActive && !this.shouldStop) { console.warn('attempt to start already running engine!') return } @@ -10,16 +10,16 @@ export function start(): void { return } - this.isActive.value = true - this.shouldStop.value = false + this.isActive = true + this.shouldStop = false this.fetchUpdate() console.log('start engine') } export function stop(): void { - if (this.isActive.value) { - this.shouldStop.value = true + if (this.isActive) { + this.shouldStop = true console.log('shut down engine') } } \ No newline at end of file diff --git a/client/src/composables/useEngine.ts b/client/src/composables/useEngine.ts index 5169d54..553d685 100644 --- a/client/src/composables/useEngine.ts +++ b/client/src/composables/useEngine.ts @@ -1,12 +1,13 @@ -import { useState } from '#app' -import { Ref } from 'vue' +import { callApi, QueryParams } from '@/composables/engine/callApi' import { start, stop } from '@/composables/engine/startStop' import { fetchUpdate } from '@/composables/engine/fetchUpdate' interface EngineContext { - isActive: Ref - shouldStop: Ref + isActive: boolean + shouldStop: boolean + version: number fetchUpdate: () => void + callApi: (url: string, queryParams?: QueryParams) => Promise } export interface useEngine { @@ -17,8 +18,10 @@ export interface useEngine { export default (): useEngine => { const context: EngineContext = { - isActive: useState('engine__is-active', () => false), - shouldStop: useState('engine__should-stop', () => false), + isActive: false, + shouldStop: false, + version: -1, + callApi, fetchUpdate, } diff --git a/client/src/stores/UserinfoStore.ts b/client/src/stores/UserinfoStore.ts index 4a1f7e2..d2c55e0 100644 --- a/client/src/stores/UserinfoStore.ts +++ b/client/src/stores/UserinfoStore.ts @@ -13,6 +13,9 @@ export const useUserinfoStore = defineStore('UserinfoStore', { isGamemaster(): boolean { return this.userInfo && ( this.userInfo.role === 'gamemaster' || this.userInfo.role === 'admin' ) }, + gameId(): string | null { + return this.userInfo?.game + }, }, actions: { setUserInfo(userInfo: unknown): void { diff --git a/client/yarn.lock b/client/yarn.lock index f8b7256..42ee9f8 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -1023,6 +1023,11 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +build-url@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/build-url/-/build-url-6.0.1.tgz#b16505136248e24b1b6d7ccab99c7ee73cd962a7" + integrity sha512-FEmyP+3hCVoBBxGZEfC8WCTvqASZb+QOvTznddKCBgdxZFqTww1+7vtZP0TUIL0/8sup0m0QpKaOaj/V4Mol0w== + builtin-modules@^3.0.0: version "3.3.0" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" diff --git a/server/data/users/d06fb83a-51eb-477e-b57c-6138a38eecb5.json b/server/data/users/d06fb83a-51eb-477e-b57c-6138a38eecb5.json index 45b2997..8f4b5e5 100644 --- a/server/data/users/d06fb83a-51eb-477e-b57c-6138a38eecb5.json +++ b/server/data/users/d06fb83a-51eb-477e-b57c-6138a38eecb5.json @@ -1 +1 @@ -{"authcode":"123456","name":"Harry","role":"player","game":"663576f0-1378-496b-a970-578bdcb222af","created":1650831122,"lastLoggedIn":1651556261} \ No newline at end of file +{"authcode":"123456","name":"Harry","role":"player","game":"663576f0-1378-496b-a970-578bdcb222af","created":1650831122,"lastLoggedIn":1659475977} \ No newline at end of file