KI-AGENT: Matrix-Chat Rate-Limits reduzieren

This commit is contained in:
2026-05-18 17:49:31 +02:00
parent 8b40be7909
commit b1e102ca5d
2 changed files with 48 additions and 12 deletions

View File

@@ -29,6 +29,15 @@ type MatrixJoinedMembersResponse = {
}> }>
} }
type MatrixUserSession = {
accessToken: string
matrixUserId: string
validUntilMs: number
}
const matrixUserSessionCache = new Map<string, MatrixUserSession>()
const matrixJoinedRoomCache = new Map<string, number>()
const trimTrailingSlash = (value: string) => value.replace(/\/+$/, "") const trimTrailingSlash = (value: string) => value.replace(/\/+$/, "")
const readLocalDevRegistrationSharedSecret = () => { const readLocalDevRegistrationSharedSecret = () => {
if (process.env.NODE_ENV === "production") return "" if (process.env.NODE_ENV === "production") return ""
@@ -296,11 +305,18 @@ export function matrixService(server: FastifyInstance) {
} }
const createAccessTokenForUser = async (userId: string, tenantId: number | null) => { const createAccessTokenForUser = async (userId: string, tenantId: number | null) => {
const matrixUserId = await matrixUserIdForUser(userId, tenantId)
const cacheKey = `${tenantId || "global"}:${userId}`
const cachedSession = matrixUserSessionCache.get(cacheKey)
if (cachedSession && cachedSession.validUntilMs > Date.now() + 60_000) {
return cachedSession
}
await provisionCurrentUser(userId, tenantId) await provisionCurrentUser(userId, tenantId)
const matrixUserId = await matrixUserIdForUser(userId, tenantId)
const serviceLogin = await ensureServiceAccessToken() const serviceLogin = await ensureServiceAccessToken()
const validUntilMs = Date.now() + 10 * 60 * 1000 const validUntilMs = Date.now() + 30 * 60 * 1000
const login = await requestMatrixJson<{ access_token: string }>( const login = await requestMatrixJson<{ access_token: string }>(
`/_synapse/admin/v1/users/${encodeURIComponent(matrixUserId)}/login`, `/_synapse/admin/v1/users/${encodeURIComponent(matrixUserId)}/login`,
@@ -312,11 +328,14 @@ export function matrixService(server: FastifyInstance) {
} }
) )
return { const session = {
accessToken: login.access_token, accessToken: login.access_token,
matrixUserId, matrixUserId,
validUntilMs, validUntilMs,
} }
matrixUserSessionCache.set(cacheKey, session)
return session
} }
const getStatus = async () => { const getStatus = async () => {
@@ -655,6 +674,12 @@ export function matrixService(server: FastifyInstance) {
room: { roomId: string, alias: string } room: { roomId: string, alias: string }
) => { ) => {
const session = await createAccessTokenForUser(userId, tenantId) const session = await createAccessTokenForUser(userId, tenantId)
const joinCacheKey = `${session.matrixUserId}:${room.roomId || room.alias}`
const joinedUntil = matrixJoinedRoomCache.get(joinCacheKey)
if (joinedUntil && joinedUntil > Date.now()) {
return session
}
try { try {
await requestMatrixJson( await requestMatrixJson(
@@ -672,6 +697,7 @@ export function matrixService(server: FastifyInstance) {
} }
} }
matrixJoinedRoomCache.set(joinCacheKey, Date.now() + 30 * 60 * 1000)
return session return session
} }

View File

@@ -24,6 +24,8 @@ const matrixMessageSending = ref(false)
const matrixAutoRefreshActive = ref(false) const matrixAutoRefreshActive = ref(false)
const lastUpdated = ref(null) const lastUpdated = ref(null)
let matrixRefreshInterval = null let matrixRefreshInterval = null
let matrixMessagesRequestActive = false
let matrixMembersRequestActive = false
const statusItems = computed(() => [ const statusItems = computed(() => [
{ {
@@ -125,7 +127,7 @@ const loadMatrixInfo = async () => {
lastUpdated.value = new Date() lastUpdated.value = new Date()
if (generalRoomRes?.exists && canUseMatrixChat.value) { if (generalRoomRes?.exists && canUseMatrixChat.value) {
await loadGeneralChat({ silent: true }) await loadGeneralChat({ silent: true, includeMembers: true })
} }
} catch (error) { } catch (error) {
toast.add({ toast.add({
@@ -225,7 +227,7 @@ const provisionGeneralRoom = async () => {
color: "success" color: "success"
}) })
await loadGeneralChat() await loadGeneralChat({ includeMembers: true })
} catch (error) { } catch (error) {
toast.add({ toast.add({
title: "Allgemeiner Chat konnte nicht erstellt werden", title: "Allgemeiner Chat konnte nicht erstellt werden",
@@ -238,6 +240,9 @@ const provisionGeneralRoom = async () => {
const loadGeneralMessages = async ({ silent = false } = {}) => { const loadGeneralMessages = async ({ silent = false } = {}) => {
if (!canUseMatrixChat.value) return if (!canUseMatrixChat.value) return
if (matrixMessagesRequestActive) return
matrixMessagesRequestActive = true
if (!silent) matrixMessagesLoading.value = true if (!silent) matrixMessagesLoading.value = true
try { try {
@@ -258,12 +263,16 @@ const loadGeneralMessages = async ({ silent = false } = {}) => {
}) })
} }
} finally { } finally {
matrixMessagesRequestActive = false
if (!silent) matrixMessagesLoading.value = false if (!silent) matrixMessagesLoading.value = false
} }
} }
const loadGeneralMembers = async ({ silent = false } = {}) => { const loadGeneralMembers = async ({ silent = false } = {}) => {
if (!canUseMatrixChat.value) return if (!canUseMatrixChat.value) return
if (matrixMembersRequestActive) return
matrixMembersRequestActive = true
if (!silent) matrixMembersLoading.value = true if (!silent) matrixMembersLoading.value = true
try { try {
@@ -277,15 +286,17 @@ const loadGeneralMembers = async ({ silent = false } = {}) => {
}) })
} }
} finally { } finally {
matrixMembersRequestActive = false
if (!silent) matrixMembersLoading.value = false if (!silent) matrixMembersLoading.value = false
} }
} }
const loadGeneralChat = async ({ silent = false } = {}) => { const loadGeneralChat = async ({ silent = false, includeMembers = false } = {}) => {
await Promise.all([ await loadGeneralMessages({ silent })
loadGeneralMessages({ silent }),
loadGeneralMembers({ silent }) if (includeMembers) {
]) await loadGeneralMembers({ silent })
}
} }
const sendMatrixMessage = async () => { const sendMatrixMessage = async () => {
@@ -321,7 +332,6 @@ const sendMatrixMessage = async () => {
matrixMessages.value = matrixMessages.value.map((item) => matrixMessages.value = matrixMessages.value.map((item) =>
item.id === optimisticId ? message : item item.id === optimisticId ? message : item
) )
await loadGeneralMembers({ silent: true })
} catch (error) { } catch (error) {
matrixMessages.value = matrixMessages.value.map((item) => matrixMessages.value = matrixMessages.value.map((item) =>
item.id === optimisticId ? { ...item, pending: false, failed: true } : item item.id === optimisticId ? { ...item, pending: false, failed: true } : item
@@ -343,7 +353,7 @@ const startMatrixAutoRefresh = () => {
if (!document.hidden && canUseMatrixChat.value) { if (!document.hidden && canUseMatrixChat.value) {
loadGeneralChat({ silent: true }) loadGeneralChat({ silent: true })
} }
}, 5000) }, 15000)
} }
const stopMatrixAutoRefresh = () => { const stopMatrixAutoRefresh = () => {