matrix-js-sdk
matrix-js-sdk copied to clipboard
Client (or sync) wont stop, even with .stopClient()
Hello,
I am trying to use this module to send a notification at the end of a script. It works, except that the client only stops several minutes after calling the .stopClient() function. So my program is still awake during this time.
The program blocks after
stopping OutgoingRoomKeyRequestManager
stopping MatrixClient
SyncApi.stop
And finally after many minutes I get Sync no longer running: exiting and the program finally stops.
How can I force the client (and the synchronization) to stop immediately?
Here is the code i'm using:
import * as sdk from 'matrix-js-sdk'
import { logger } from 'matrix-js-sdk/lib/logger.js'
import { ClientEvent } from 'matrix-js-sdk'
import Olm from "olm/olm_legacy.js"
import { LocalStorage } from 'node-localstorage'
import { LocalStorageCryptoStore } from 'matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js'
// temp fix : https://github.com/matrix-org/matrix-js-sdk/issues/2415#issuecomment-1141246410
import request from "request"
///
global.Olm = Olm
const localStorage = new LocalStorage('./store/matrix')
export class Matrix {
matrixClient
connected
constructor(url, user, token) {
this.connected = false
// temp fix : https://github.com/matrix-org/matrix-js-sdk/issues/2415#issuecomment-1141246410
sdk.request(request)
///
this.matrixClient = sdk.createClient({
deviceId: "Streaks Server",
baseUrl: url,
accessToken: token,
userId: user,
sessionStore: new sdk.MemoryStore({ localStorage }),
cryptoStore: new LocalStorageCryptoStore(localStorage)
})
}
async connect() {
if (this.connected)
return
//logger.setLevel(logger.levels.ERROR)
await this.matrixClient.initCrypto()
await this.matrixClient.startClient()
await new Promise((resolve, _reject) => {
this.matrixClient.once(ClientEvent.Sync, () => {
// Send encrypted message, even if member isn't trusted
this.matrixClient.setGlobalErrorOnUnknownDevices(false)
this.connected = true
resolve()
})
})
}
disconnect() {
if (!this.connected)
return
this.matrixClient.stopClient()
}
async sendMessage(roomID, message) {
await this.matrixClient.joinRoom(roomID)
await this.matrixClient.uploadKeys()
await this.matrixClient.sendTextMessage(roomID, message)
}
}
const config = {
matrix: {
url: process.env['MATRIX_URL'],
user: process.env['MATRIX_USER'],
token: process.env['MATRIX_TOKEN'],
roomID: process.env['MATRIX_ROOM']
}
}
let matrix = new Matrix(config.matrix.url, config.matrix.user, config.matrix.token)
await matrix.connect()
await matrix.sendMessage(config.matrix.roomID, "Hello world!")
matrix.disconnect()
This is not possible with the current request interface, blocked on https://github.com/matrix-org/matrix-js-sdk/issues/801
I tracked this down to 2 specific timeouts: https://github.com/matrix-org/matrix-js-sdk/blob/858155e0efc910e5e094803bb71af78d42419780/src/crypto/index.ts#L2037-L2040 and https://github.com/matrix-org/matrix-js-sdk/blob/858155e0efc910e5e094803bb71af78d42419780/src/http-api/utils.ts#L26-L28
As a workaround you can use pnpm patch to patch this package. Specifically in node, timers have an unref() method that tells node that its ok to end the process if the timer is still running.
I patched both of these setTimeout like so:
setTimeout(....).unref();
and that allowed node to exit immediately after calling the stopClient() method.
I am writing some Jest based integration tests and ran into this issue:
Jest did not exit 5 seconds after the test run has completed.
'This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
Temporary workaround for anyone using Jest is to run it with the --forceExit flag, so:
"scripts": {
...
"test": "jest --forceExit",
...
}