Skip to content

Commit f482649

Browse files
committed
Improve design
1 parent 50de2d0 commit f482649

File tree

5 files changed

+69
-52
lines changed

5 files changed

+69
-52
lines changed

packages/testkit-backend/src/backend.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ export default class Backend {
77
this._controller = newController()
88

99
this._controller.on('response', ({ contextId, response }) => {
10-
this._socketServer.writeResponse(contextId, response.name, response.data)
10+
this._socketServer.writeResponse(contextId, response)
1111
})
1212

1313
this._socketServer.on('contextOpen', ({ contextId }) => this._controller.onContextOpen(contextId))
1414
this._socketServer.on('contextClose', ({ contextId }) => this._controller.onContextClose(contextId))
1515

1616
this._socketServer.on('request', ({ contextId, request }) => {
1717
try {
18-
this._controller.handle(contextId, request.name, request.data )
18+
this._controller.handle(contextId, request)
1919
} catch (e) {
2020
this._socketServer.writeBackendError(contextId, e)
2121
}
@@ -33,4 +33,3 @@ export default class Backend {
3333
}
3434

3535
}
36-

packages/testkit-backend/src/controller.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default class Controller extends EventEmitter {
1818
throw new Error('not implemented')
1919
}
2020

21-
handle(contextId, name, data) {
21+
handle(contextId, request) {
2222
throw new Error('not implemented')
2323
}
24-
}
24+
}

packages/testkit-backend/src/node.controller.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default class NodeController extends Controller {
2020
}
2121

2222

23-
handle(contextId, name, data) {
23+
handle(contextId, { name, data }) {
2424
if (!this._contexts.has(contextId)) {
2525
throw new Error(`Context ${contextId} does not exist`)
2626
} else if (!(name in this._requestHandlers)) {
@@ -64,4 +64,4 @@ export default class NodeController extends Controller {
6464
this._writeBackendError(contextId, e)
6565
}
6666

67-
}
67+
}
+30-15
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,31 @@
1-
1+
import readline from 'readline'
22
import EventEmitter from 'events'
33

44
export default class Protocol extends EventEmitter {
5-
constructor () {
5+
constructor (stream) {
66
super()
7-
console.log('Backend connected')
87
this._inRequest = false
98
this._request = ''
9+
this._stream = stream
10+
this._readlineInterface = null
11+
}
12+
13+
start() {
14+
if (!this._readlineInterface) {
15+
this._readlineInterface = readline.createInterface(this._stream, null)
16+
this._readlineInterface.on('line', this._processLine.bind(this))
17+
}
18+
}
19+
20+
stop () {
21+
if (this._readlineInterface) {
22+
this._readlineInterface.off('line', this._processLine.bind(this))
23+
this._readlineInterface = null
24+
}
1025
}
1126

1227
// Called whenever a new line is received.
13-
processLine (line) {
28+
_processLine (line) {
1429
switch (line) {
1530
case '#request begin':
1631
if (this._inRequest) {
@@ -26,28 +41,28 @@ export default class Protocol extends EventEmitter {
2641
this._emitRequest()
2742
} catch (e) {
2843
console.log('error', e)
29-
this.emit('error', e)
44+
this._emitError(e)
3045
}
3146
this._request = ''
3247
this._inRequest = false
3348
break
3449
default:
3550
if (!this._inRequest) {
36-
throw new Error('Line while not in request')
51+
this._emitError(new Error('Line while not in request'))
3752
}
3853
this._request += line
3954
break
4055
}
4156
}
4257

43-
serializeResponse (name, data) {
44-
console.log('> writing response', name, data)
45-
let response = {
46-
name: name,
47-
data: data
48-
}
49-
response = this._stringify(response)
50-
return ['#response begin', response, '#response end'].join('\n') + '\n'
58+
_emitError(e) {
59+
this.emit('error', e)
60+
}
61+
62+
serializeResponse (response) {
63+
console.log('> writing response', response)
64+
const responseStr = this._stringify(response)
65+
return ['#response begin', responseStr, '#response end'].join('\n') + '\n'
5166
}
5267

5368
_emitRequest () {
@@ -62,4 +77,4 @@ export default class Protocol extends EventEmitter {
6277
typeof value === 'bigint' ? `${value}n` : value
6378
)
6479
}
65-
}
80+
}
+33-30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
import readline from 'readline'
31
import { EventEmitter } from 'events'
42
import net from 'net'
53
import { randomBytes } from 'crypto'
@@ -10,7 +8,7 @@ function generateRandomId () {
108
}
119

1210
export default class SocketServer extends EventEmitter {
13-
constructor(port, newProtocol = () => new Protocol(), newId = generateRandomId ) {
11+
constructor(port, newProtocol = stream => new Protocol(stream), newId = generateRandomId ) {
1412
super()
1513
this._newProtocol = newProtocol
1614
this._server = null
@@ -21,28 +19,7 @@ export default class SocketServer extends EventEmitter {
2119

2220
start () {
2321
if (!this._server) {
24-
this._server = net.createServer(connection => {
25-
const contextId = this._newId()
26-
console.log(`[${contextId}] Creating connection`)
27-
const protocol = this._newProtocol()
28-
29-
this._clients.set(contextId, {
30-
protocol,
31-
connection
32-
})
33-
34-
this.emit('contextOpen', { contextId })
35-
protocol.on('request', request => this.emit('request', { contextId, request }) )
36-
protocol.on('error', e => this.writeBackendError(contextId, e))
37-
38-
connection.on('end', () => {
39-
this._clients.delete(contextId)
40-
this.emit('contextClose', { contextId })
41-
})
42-
43-
const iface = readline.createInterface(connection, null)
44-
iface.on('line', protocol.processLine.bind(protocol))
45-
})
22+
this._server = net.createServer(this._handleConnection.bind(this))
4623

4724
this._server.listen(this._port, () => {
4825
console.log('Listening')
@@ -52,24 +29,50 @@ export default class SocketServer extends EventEmitter {
5229
}
5330
}
5431

55-
writeResponse (contextId, name, data) {
32+
_handleConnection(connection) {
33+
console.log('Backend connected')
34+
35+
const contextId = this._newId()
36+
const protocol = this._newProtocol(connection)
37+
38+
this._clients.set(contextId, {
39+
protocol,
40+
connection
41+
})
42+
43+
this.emit('contextOpen', { contextId })
44+
protocol.on('request', request => this.emit('request', { contextId, request }) )
45+
protocol.on('error', e => this.writeBackendError(contextId, e))
46+
47+
connection.on('end', () => {
48+
if (this._clients.has(contextId)) {
49+
this._clients.get(contextId).protocol.stop()
50+
}
51+
this._clients.delete(contextId)
52+
this.emit('contextClose', { contextId })
53+
})
54+
55+
protocol.start()
56+
}
57+
58+
writeResponse (contextId, response) {
5659
if (this._clients.has(contextId)) {
5760
const { protocol, connection } = this._clients.get(contextId)
58-
const chunk = protocol.serializeResponse(name, data)
61+
const chunk = protocol.serializeResponse(response)
5962
connection.write(chunk, 'utf8', () => {})
60-
6163
}
6264
}
6365

6466
writeBackendError (contextId, error) {
65-
this.writeResponse(contextId, 'BackendError', { msg: error})
67+
this.writeResponse(contextId, { name: 'BackendError', data: { msg: error } })
6668
}
6769

6870
stop () {
6971
if (this._server) {
7072
this._server.close()
73+
this._server = null
74+
this._clients.forEach(client => client.protocol.stop())
7175
this._clients = new Map()
7276
}
7377
}
74-
7578
}

0 commit comments

Comments
 (0)