@samitouri / QOSami-HFS / commits / 8bccd31d

fix: possible "reading busy" error in the admin-panel #327

Massimo Melina committed Aug 27, 2023 at 20:31 UTC 8bccd31d4e3a8d1a9ec0d96017a282000132d0de
1 file changed +9 -8
src/listen.ts
+9 -8
@@ -15,8 +15,8 @@ import { anyAccountCanLoginAdmin } from './adminApis'
15 import _ from 'lodash'
16
17 interface ServerExtra { name: string, error?: string, busy?: Promise<string> }
18 -let httpSrv: http.Server & ServerExtra
19 -let httpsSrv: http.Server & ServerExtra
18 +let httpSrv: undefined | http.Server & ServerExtra
19 +let httpsSrv: undefined | http.Server & ServerExtra
20
21 const openBrowserAtStart = defineConfig('open_browser_at_start', !DEV)
22
@@ -42,7 +42,7 @@ export function openAdmin() {
42 for (const srv of [httpSrv, httpsSrv]) {
43 const a = srv?.address()
44 if (!a || typeof a === 'string') continue
45 - const baseUrl = srv.name + '://localhost:' + a.port
45 + const baseUrl = srv!.name + '://localhost:' + a.port
46 open(baseUrl + ADMIN_URI, { wait: true}).catch(e => {
47 console.debug(String(e))
48 console.warn("cannot launch browser on this machine >PLEASE< open your browser and reach one of these (you may need a different address)",
@@ -76,7 +76,7 @@ const considerHttps = debounceAsync(async () => {
76 }
77 }
78 catch(e) {
79 - httpsSrv.error = "bad private key or certificate"
79 + httpsSrv!.error = "bad private key or certificate"
80 console.log("failed to create https server: check your private key and certificate", String(e))
81 return
82 }
@@ -116,6 +116,7 @@ httpsPortCfg.sub(considerHttps)
116 interface StartServer { port: number, host?:string }
117 function startServer(srv: typeof httpSrv, { port, host }: StartServer) {
118 return new Promise<number>(async resolve => {
119 + if (!srv) return 0
120 try {
121 if (port < 0 || !host && !await testIpV4()) // !host means ipV4+6, and if v4 port alone is busy we won't be notified of the failure, so we'll first test it on its own
122 return resolve(0)
@@ -135,13 +136,13 @@ function startServer(srv: typeof httpSrv, { port, host }: StartServer) {
136
137 async function testIpV4() {
138 const res = await listen('0.0.0.0')
138 - await new Promise(res => srv.close(res))
139 + await new Promise(res => srv?.close(res))
140 return res > 0
141 }
142
143 function listen(host?: string) {
144 return new Promise<number>(async (resolve, reject) => {
144 - srv.listen({ port, host }, () => {
145 + srv?.listen({ port, host }, () => {
146 const ad = srv.address()
147 if (!ad)
148 return reject('no address')
@@ -167,7 +168,7 @@ function startServer(srv: typeof httpSrv, { port, host }: StartServer) {
168 }
169 }
170
170 -function stopServer(srv: http.Server) {
171 +function stopServer(srv?: http.Server) {
172 return new Promise(resolve => {
173 if (!srv?.listening)
174 return resolve(null)
@@ -189,7 +190,7 @@ export async function getServerStatus() {
190 }
191
192 async function serverStatus(h: typeof httpSrv, configuredPort?: number) {
192 - const busy = await h.busy
193 + const busy = await h?.busy
194 await wait(0) // simple trick to wait for also .error to be updated. If this trickery becomes necessary elsewhere, then we should make also error a Promise.
195 return {
196 ..._.pick(h, ['listening', 'error']),