service.js 7.8 KB
Newer Older
H
Hao Sun 已提交
1 2
import path from 'path';
import {spawn} from 'child_process';
H
Hao Sun 已提交
3
import os from 'os';
4 5
import {app} from 'electron';
import express from 'express';
aaronchen2k2k's avatar
aaronchen2k2k 已提交
6
import {logInfo, logErr} from './log';
H
Hao Sun 已提交
7

H
Hao Sun 已提交
8 9
const DEBUG = process.env.NODE_ENV === 'development';

H
Hao Sun 已提交
10 11 12
let _ztfServerProcess;

export function startZtfServer() {
13
    if (process.env.SKIP_SERVER) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
14
        logInfo(`>> Skip to start ZTF Server by env "SKIP_SERVER=${process.env.SKIP_SERVER}".`);
15 16
        return Promise.resolve();
    }
H
Hao Sun 已提交
17 18 19 20
    if (_ztfServerProcess) {
        return Promise.resolve(_ztfServerProcess);
    }

21
    let {SERVER_EXE_PATH: serverExePath} = process.env;
H
Hao Sun 已提交
22
    if (!serverExePath && !DEBUG) {
H
Hao Sun 已提交
23 24
        const platform = os.platform(); // 'darwin', 'linux', 'win32'
        const exePath = `bin/${platform}/ztf${platform === 'win32' ? '.exe' : ''}`;
25
        serverExePath = path.join(process.resourcesPath, exePath);
H
Hao Sun 已提交
26
    }
27 28 29 30
    if (serverExePath) {
        if (!path.isAbsolute(serverExePath)) {
            serverExePath = path.resolve(app.getAppPath(), serverExePath);
        }
H
Hao Sun 已提交
31
        return new Promise((resolve, reject) => {
32
            const cwd = process.env.SERVER_CWD_PATH || path.dirname(serverExePath);
aaronchen2k2k's avatar
aaronchen2k2k 已提交
33
            logInfo(`>> Starting ZTF Server from exe path with command "${serverExePath} -P 8085" in "${cwd}"...`);
H
Hao Sun 已提交
34
            const cmd = spawn(serverExePath, ['-P', '8085'], {
35
                cwd,
H
Hao Sun 已提交
36 37
                shell: true,
            });
H
Hao Sun 已提交
38
            cmd.on('close', (code) => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
39
                logInfo(`>> ZTF server closed with code ${code}`);
H
Hao Sun 已提交
40
                _ztfServerProcess = null;
aaronchen2k2k's avatar
aaronchen2k2k 已提交
41
                cmd.kill()
H
Hao Sun 已提交
42 43 44 45 46 47
            });
            cmd.stdout.on('data', data => {
                const dataString = String(data);
                const lines = dataString.split('\n');
                for (let i = 0; i < lines.length; i++) {
                    const line = lines[i];
H
Hao Sun 已提交
48
                    if (DEBUG) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
49
                        logInfo('\t' + line);
H
Hao Sun 已提交
50
                    }
H
Hao Sun 已提交
51 52
                    if (line.includes('Now listening on: http')) {
                        resolve(line.split('Now listening on:')[1].trim());
H
Hao Sun 已提交
53 54 55
                        if (!DEBUG) {
                            break;
                        }
H
Hao Sun 已提交
56 57
                    } else if (line.includes('启动HTTP服务于')) {
                        resolve(line.split(/启动HTTP服务于|,/)[1].trim());
H
Hao Sun 已提交
58 59 60
                        if (!DEBUG) {
                            break;
                        }
H
Hao Sun 已提交
61 62
                    } else if (line.startsWith('[ERRO]')) {
                        reject(new Error(`Start ztf server failed with error: ${line.substring('[ERRO]'.length)}`));
H
Hao Sun 已提交
63 64 65
                        if (!DEBUG) {
                            break;
                        }
H
Hao Sun 已提交
66 67
                    }
                }
H
Hao Sun 已提交
68
            });
H
Hao Sun 已提交
69 70 71 72 73
            cmd.on('error', spawnError => {
                console.error('>>> Start ztf server failed with error', spawnError);
                reject(spawnError)
            });
            _ztfServerProcess = cmd;
H
Hao Sun 已提交
74 75 76 77
        });
    }

    return new Promise((resolve, reject) => {
78
        const cwd = process.env.SERVER_CWD_PATH || path.resolve(app.getAppPath(), '../');
aaronchen2k2k's avatar
aaronchen2k2k 已提交
79
        logInfo(`>> Starting ZTF development server from source with command "go run cmd/server/main.go -P 8085" in "${cwd}"`);
H
Hao Sun 已提交
80
        const cmd = spawn('go', ['run', 'main.go', '-P', '8085'], {
81
            cwd,
H
Hao Sun 已提交
82 83
            shell: true,
        });
H
Hao Sun 已提交
84
        cmd.on('close', (code) => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
85
            logInfo(`>> ZTF server closed with code ${code}`);
H
Hao Sun 已提交
86 87 88 89
            _ztfServerProcess = null;
        });
        cmd.stdout.on('data', data => {
            const dataString = String(data);
90 91 92
            const lines = dataString.split('\n');
            for (let i = 0; i < lines.length; i++) {
                const line = lines[i];
H
Hao Sun 已提交
93
                if (DEBUG) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
94
                    logInfo('\t' + line);
H
Hao Sun 已提交
95
                }
96 97
                if (line.includes('Now listening on: http')) {
                    resolve(line.split('Now listening on:')[1].trim());
H
Hao Sun 已提交
98 99 100
                    if (!DEBUG) {
                        break;
                    }
101 102
                } else if (line.startsWith('[ERRO]')) {
                    reject(new Error(`Start ztf server failed with error: ${line.substring('[ERRO]'.length)}`));
H
Hao Sun 已提交
103 104 105
                    if (!DEBUG) {
                        break;
                    }
106
                }
H
Hao Sun 已提交
107 108 109 110 111 112 113 114 115 116
            }
        });
        cmd.on('error', spawnError => {
            console.error('>>> Start ztf server failed with error', spawnError);
            reject(spawnError)
        });
        _ztfServerProcess = cmd;
    });
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
117 118 119 120
export function killZtfServer() {
    _ztfServerProcess.kill('SIGINT');
}

121
let _uiServerApp;
H
Hao Sun 已提交
122 123

export function getUIServerUrl() {
124 125
    if (_uiServerApp) {
        return Promise.resolve();
H
Hao Sun 已提交
126 127
    }

128
    let {UI_SERVER_URL: uiServerUrl} = process.env;
H
Hao Sun 已提交
129
    if (!uiServerUrl && !DEBUG) {
H
Hao Sun 已提交
130 131 132
        uiServerUrl = path.resolve(process.resourcesPath, 'ui');
    }

133 134 135 136 137 138 139 140 141
    if (uiServerUrl) {
        if (/^https?:\/\//.test(uiServerUrl)) {
            return Promise.resolve(uiServerUrl);
        }
        return new Promise((resolve, reject) => {
            if (!path.isAbsolute(uiServerUrl)) {
                uiServerUrl = path.resolve(app.getAppPath(), uiServerUrl);
            }

H
Hao Sun 已提交
142
            const port = process.env.UI_SERVER_PORT || 8000;
aaronchen2k2k's avatar
aaronchen2k2k 已提交
143
            logInfo(`>> Starting UI serer at ${uiServerUrl} with port ${port}`);
144 145 146

            const uiServer = express();
            uiServer.use(express.static(uiServerUrl));
H
Hao Sun 已提交
147
            const server = uiServer.listen(port, serverError => {
148 149 150 151 152
                if (serverError) {
                    console.error('>>> Start ui server failed with error', serverError);
                    _uiServerApp = null;
                    reject(serverError);
                } else {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
153
                    logInfo(`>> UI server started successfully on http://localhost:${port}.`);
H
Hao Sun 已提交
154
                    resolve(`http://localhost:${port}`);
155
                }
H
Hao Sun 已提交
156
            });
157 158 159 160 161
            server.on('close', () => {
                _uiServerApp = null;
            });
            _uiServerApp = uiServer;
        })
H
Hao Sun 已提交
162 163 164
    }

    return new Promise((resolve, reject) => {
H
Hao Sun 已提交
165
        const cwd = path.resolve(app.getAppPath(), '../ui');
aaronchen2k2k's avatar
aaronchen2k2k 已提交
166
        logInfo(`>> Starting UI development server with command "npm run serve" in "${cwd}"...`);
167

H
Hao Sun 已提交
168 169
        let resolved = false;
        const cmd = spawn('npm', ['run', 'serve'], {
H
Hao Sun 已提交
170
            cwd,
H
Hao Sun 已提交
171 172
            shell: true,
        });
H
Hao Sun 已提交
173
        cmd.on('close', (code) => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
174
            logInfo(`>> ZTF server closed with code ${code}`);
175
            _uiServerApp = null;
H
Hao Sun 已提交
176 177 178 179 180 181 182 183 184
        });
        cmd.stdout.on('data', data => {
            if (resolved) {
                return;
            }
            const dataString = String(data);
            const lines = dataString.split('\n');
            for (let i = 0; i < lines.length; i++) {
                const line = lines[i];
H
Hao Sun 已提交
185
                if (DEBUG) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
186
                    logInfo('\t' + line);
H
Hao Sun 已提交
187
                }
H
Hao Sun 已提交
188
                if (line.includes('App running at:')) {
189
                    const nextLine = lines[i + 1] || lines[i + 2];
H
Hao Sun 已提交
190
                    if (DEBUG) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
191
                        logInfo('\t' + nextLine);
H
Hao Sun 已提交
192
                    }
H
Hao Sun 已提交
193
                    if (!nextLine) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
194
                        console.error('\t' + `Cannot grabing running address after line "${line}".`);
H
Hao Sun 已提交
195
                        throw new Error(`Cannot grabing running address after line "${line}".`);
H
Hao Sun 已提交
196
                    }
H
Hao Sun 已提交
197
                    const url = nextLine.split('Local:   ')[1];
198 199 200 201
                    if (url) {
                        resolved = true;
                        resolve(url);
                    }
H
Hao Sun 已提交
202 203 204
                    if (!DEBUG) {
                        break;
                    }
H
Hao Sun 已提交
205 206 207 208 209 210 211
                }
            }
        });
        cmd.on('error', spawnError => {
            console.error('>>> Get ui server url failed with error', spawnError);
            reject(spawnError)
        });
212
        _uiServerApp = cmd;
H
Hao Sun 已提交
213 214
    });
}