Add better shutdown handling
This commit is contained in:
parent
938068703b
commit
814c8cbdb3
|
@ -24,17 +24,25 @@ export default class PuppetAPI {
|
|||
path = "/var/run/mautrix-amp/puppet.sock"
|
||||
|
||||
constructor() {
|
||||
this.server = net.createServer(sock =>
|
||||
new Client(this, sock, ++this.connIDSequence).start())
|
||||
this.server = net.createServer(this.acceptConnection)
|
||||
this.puppets = new Map()
|
||||
this.clients = new Map()
|
||||
this.connIDSequence = 0
|
||||
this.stopped = false
|
||||
}
|
||||
|
||||
log(...text) {
|
||||
console.log("[API]", ...text)
|
||||
}
|
||||
|
||||
acceptConnection = sock => {
|
||||
if (this.stopped) {
|
||||
sock.end()
|
||||
} else {
|
||||
new Client(this, sock, ++this.connIDSequence).start()
|
||||
}
|
||||
}
|
||||
|
||||
async start() {
|
||||
this.log("Starting server")
|
||||
|
||||
|
@ -52,15 +60,16 @@ export default class PuppetAPI {
|
|||
}
|
||||
|
||||
async stop() {
|
||||
this.stopped = true
|
||||
for (const client of this.clients.values()) {
|
||||
await client.stop("Server is shutting down")
|
||||
}
|
||||
this.log("Stopping server")
|
||||
await promisify(cb => this.server.close(cb))
|
||||
try {
|
||||
await fs.promises.unlink(this.path)
|
||||
} catch (err) {}
|
||||
this.log("Server stopped")
|
||||
for (const client of this.clients.values()) {
|
||||
await client.stop()
|
||||
}
|
||||
for (const puppet of this.puppets.values()) {
|
||||
await puppet.stop()
|
||||
}
|
||||
|
|
|
@ -43,6 +43,14 @@ export default class Client {
|
|||
}
|
||||
}
|
||||
|
||||
error(...text) {
|
||||
if (this.userID) {
|
||||
console.error(`[API/${this.userID}/${this.connID}]`, ...text)
|
||||
} else {
|
||||
console.error(`[API/${this.connID}]`, ...text)
|
||||
}
|
||||
}
|
||||
|
||||
start() {
|
||||
this.log("Received connection", this.connID)
|
||||
emitLines(this.socket)
|
||||
|
@ -53,17 +61,23 @@ export default class Client {
|
|||
setTimeout(() => {
|
||||
if (!this.userID && !this.stopped) {
|
||||
this.log("Didn't receive register request within 3 seconds, terminating")
|
||||
this.stop()
|
||||
this.stop("Register request timeout")
|
||||
}
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
stop() {
|
||||
async stop(error = null) {
|
||||
if (this.stopped) {
|
||||
return
|
||||
}
|
||||
this.stopped = true
|
||||
return promisify(cb => this.socket.end(cb))
|
||||
try {
|
||||
await this._write({ id: --this.notificationID, command: "quit", error })
|
||||
await promisify(cb => this.socket.end(cb))
|
||||
} catch (err) {
|
||||
this.error("Failed to end connection:", err)
|
||||
this.socket.destroy(err)
|
||||
}
|
||||
}
|
||||
|
||||
handleEnd = () => {
|
||||
|
@ -133,7 +147,7 @@ export default class Client {
|
|||
const oldClient = this.manager.clients.get(this.userID)
|
||||
this.manager.clients.set(this.userID, this)
|
||||
this.log("Terminating previous socket", oldClient.connID, "for", this.userID)
|
||||
await oldClient.stop()
|
||||
await oldClient.stop("Socket replaced by new connection")
|
||||
} else {
|
||||
this.manager.clients.set(this.userID, this)
|
||||
}
|
||||
|
@ -170,11 +184,11 @@ export default class Client {
|
|||
if (!this.userID) {
|
||||
if (req.command !== "register") {
|
||||
this.log("First request wasn't a register request, terminating")
|
||||
await this.stop()
|
||||
await this.stop("Invalid first request")
|
||||
return
|
||||
} else if (!req.user_id) {
|
||||
this.log("Register request didn't contain user ID, terminating")
|
||||
await this.stop()
|
||||
await this.stop("Invalid register request")
|
||||
return
|
||||
}
|
||||
handler = this.handleRegister
|
||||
|
|
Loading…
Reference in New Issue