mirror of
https://codeberg.org/timelimit/timelimit-server.git
synced 2025-10-03 09:49:32 +02:00
Save the maximum package name length which was seen
This commit is contained in:
parent
b4fd177afe
commit
ba3bb50113
5 changed files with 79 additions and 15 deletions
|
@ -14,8 +14,8 @@ Use this to get the server status.
|
|||
## Response
|
||||
|
||||
This returns a JSON object with ``websocketClients`` (of the type number,
|
||||
the number of clients connected using the websocket) and the map ``counters``
|
||||
which maps values to numbers. You should not make any assumptions about the counter names
|
||||
the number of clients connected using the websocket) and the maps ``counters`` and ``maxValues``
|
||||
which map values to numbers. You should not make any assumptions about the key names
|
||||
and their availability.
|
||||
|
||||
### example response
|
||||
|
@ -25,13 +25,16 @@ and their availability.
|
|||
"websocketClients": 3,
|
||||
"counters": {
|
||||
"testCounter": 1
|
||||
},
|
||||
"maxValues": {
|
||||
"testMax": 3
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## POST /admin/reset-counters
|
||||
|
||||
Use this to reset the counters included in the server status.
|
||||
Use this to reset the counters and maxValues included in the server status.
|
||||
|
||||
Although this uses POST, it does not take any request body
|
||||
|
||||
|
|
|
@ -34,9 +34,12 @@ export const createAdminRouter = ({ database, websocket, eventHandler }: {
|
|||
|
||||
router.get('/status', async (_, res, next) => {
|
||||
try {
|
||||
const { counters, maxValues } = await eventHandler.getValues()
|
||||
|
||||
res.json({
|
||||
websocketClients: websocket.countConnections(),
|
||||
counters: await eventHandler.getCounters()
|
||||
counters,
|
||||
maxValues
|
||||
})
|
||||
} catch (ex) {
|
||||
next(ex)
|
||||
|
@ -45,7 +48,7 @@ export const createAdminRouter = ({ database, websocket, eventHandler }: {
|
|||
|
||||
router.post('/reset-counters', async (_, res, next) => {
|
||||
try {
|
||||
await eventHandler.resetCounters()
|
||||
await eventHandler.reset()
|
||||
|
||||
res.json({ ok: true })
|
||||
} catch (ex) {
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { max } from 'lodash'
|
||||
import { AddInstalledAppsAction, AppLogicAction, UpdateAppActivitiesAction } from '../../../../action'
|
||||
import { parseAppLogicAction } from '../../../../action/serialization'
|
||||
import { ClientPushChangesRequestAction } from '../../../../api/schema'
|
||||
import { isSerializedAppLogicAction } from '../../../../api/validator'
|
||||
|
@ -23,6 +25,30 @@ import { Cache } from '../cache'
|
|||
import { dispatchAppLogicAction as dispatchAppLogicActionInternal } from '../dispatch-app-logic-action'
|
||||
import { dispatch } from './helper'
|
||||
|
||||
function getAppRelatedMaxValues (action: AppLogicAction): {
|
||||
packageNameLength: number | null
|
||||
activityNameLength: number | null
|
||||
} {
|
||||
if (action instanceof AddInstalledAppsAction) {
|
||||
const packageNameLength = max(action.apps.map((item) => item.packageName.length)) || null
|
||||
|
||||
return { packageNameLength, activityNameLength: null }
|
||||
} else if (action instanceof UpdateAppActivitiesAction) {
|
||||
const packageNameLength = max(action.updatedOrAdded.map((item) => item.packageName.length)) || null
|
||||
const activityNameLength = max(action.updatedOrAdded.map((item) => item.activityName.length)) || null
|
||||
|
||||
return { packageNameLength, activityNameLength }
|
||||
} else return { packageNameLength: null, activityNameLength: null }
|
||||
}
|
||||
|
||||
function roundCounterUp (input: number, factor: number) {
|
||||
if (input % factor === 0) {
|
||||
return input
|
||||
} else {
|
||||
return input - (input % factor) + factor
|
||||
}
|
||||
}
|
||||
|
||||
export async function dispatchAppLogicAction ({ action, eventHandler, deviceId, cache }: {
|
||||
action: ClientPushChangesRequestAction
|
||||
deviceId: string
|
||||
|
@ -36,6 +62,11 @@ export async function dispatchAppLogicAction ({ action, eventHandler, deviceId,
|
|||
validator: isSerializedAppLogicAction,
|
||||
parser: parseAppLogicAction,
|
||||
applier: async (action) => {
|
||||
const maxValues = getAppRelatedMaxValues(action)
|
||||
|
||||
if (maxValues.packageNameLength) eventHandler.reportMax('packageNameLength', roundCounterUp(maxValues.packageNameLength, 10))
|
||||
if (maxValues.activityNameLength) eventHandler.reportMax('activityNameLength', roundCounterUp(maxValues.activityNameLength, 10))
|
||||
|
||||
await dispatchAppLogicActionInternal({ action, cache, eventHandler, deviceId })
|
||||
}
|
||||
})
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
export interface EventHandler {
|
||||
countEvent (name: string): void
|
||||
getCounters (): Promise<{[key: string]: number}>
|
||||
resetCounters (): Promise<void>
|
||||
reportMax (name: string, value: number): void
|
||||
getValues (): Promise<{
|
||||
counters: {[key: string]: number}
|
||||
maxValues: {[key: string]: number}
|
||||
}>
|
||||
reset (): Promise<void>
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import { EventHandler } from './eventhandler'
|
|||
|
||||
export class InMemoryEventHandler implements EventHandler {
|
||||
private counters = new Map<string, number>()
|
||||
private maxValues = new Map<string, number>()
|
||||
|
||||
countEvent (name: string) {
|
||||
this.counters.set(
|
||||
|
@ -27,17 +28,39 @@ export class InMemoryEventHandler implements EventHandler {
|
|||
)
|
||||
}
|
||||
|
||||
async getCounters () {
|
||||
const result: {[key: string]: number} = {}
|
||||
reportMax (name: string, value: number) {
|
||||
this.maxValues.set(
|
||||
name,
|
||||
Math.max((this.maxValues.get(name) || 0), value)
|
||||
)
|
||||
}
|
||||
|
||||
this.counters.forEach((value, key) => {
|
||||
async getValues () {
|
||||
return {
|
||||
counters: this.buildObject(this.counters),
|
||||
maxValues: this.buildObject(this.maxValues)
|
||||
}
|
||||
}
|
||||
|
||||
async reset () {
|
||||
this.counters.clear()
|
||||
this.maxValues.clear()
|
||||
}
|
||||
|
||||
private buildObject<T> (map: Map<string, T>): {[key: string]: T} {
|
||||
const result: {[key: string]: T} = {}
|
||||
|
||||
const keys: Array<string> = []
|
||||
map.forEach((_, key) => keys.push(key))
|
||||
|
||||
keys.sort().forEach((key) => {
|
||||
const value = map.get(key)
|
||||
|
||||
if (value !== undefined) {
|
||||
result[key] = value
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
async resetCounters () {
|
||||
this.counters.clear()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue