* Attach a socket to this handler * @param socket The socket to attach * @returns this handler instance * @throws Error if a socket is already attached
(socket: Socket)
| 75 | * @throws Error if a socket is already attached |
| 76 | */ |
| 77 | public async attach(socket: Socket): Promise<PGLiteSocketHandler> { |
| 78 | this.log( |
| 79 | `attach: attaching socket from ${socket.remoteAddress}:${socket.remotePort}`, |
| 80 | ) |
| 81 | |
| 82 | if (this.socket) { |
| 83 | throw new Error('Socket already attached') |
| 84 | } |
| 85 | |
| 86 | this.socket = socket |
| 87 | this.active = true |
| 88 | |
| 89 | // Ensure the PGlite instance is ready |
| 90 | this.log(`attach: waiting for PGlite to be ready`) |
| 91 | await this.db.waitReady |
| 92 | |
| 93 | // Hold the lock on the PGlite instance |
| 94 | this.log(`attach: acquiring exclusive lock on PGlite instance`) |
| 95 | await new Promise<void>((resolve) => { |
| 96 | this.db.runExclusive(() => { |
| 97 | // Ensure we have the lock on the PGlite instance |
| 98 | resolve() |
| 99 | |
| 100 | // Use a promise to hold the lock on the PGlite instance |
| 101 | // this can be resolved or rejected by the handler to release the lock |
| 102 | return new Promise<void>((resolveLock, rejectLock) => { |
| 103 | this.resolveLock = resolveLock |
| 104 | this.rejectLock = rejectLock |
| 105 | }) |
| 106 | }) |
| 107 | }) |
| 108 | |
| 109 | // Setup event handlers |
| 110 | this.log(`attach: setting up socket event handlers`) |
| 111 | socket.on('data', (data) => this.handleData(data)) |
| 112 | socket.on('error', (err) => this.handleError(err)) |
| 113 | socket.on('close', () => this.handleClose()) |
| 114 | |
| 115 | return this |
| 116 | } |
| 117 | |
| 118 | /** |
| 119 | * Detach the current socket from this handler |
no test coverage detected