mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-23 03:22:19 +03:00
UBERF-6523: Allow to use zstd (#5333)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
ce7fc92e56
commit
f8cc27b590
@ -30,12 +30,8 @@
|
|||||||
endpoint = endpoint.substring(0, endpoint.length - 1)
|
endpoint = endpoint.substring(0, endpoint.length - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
let data: any
|
async function fetchStats (): Promise<void> {
|
||||||
let dataFront: any
|
await fetch(endpoint + `/api/v1/statistics?token=${token}`, {})
|
||||||
let admin = false
|
|
||||||
onDestroy(
|
|
||||||
ticker.subscribe(() => {
|
|
||||||
void fetch(endpoint + `/api/v1/statistics?token=${token}`, {})
|
|
||||||
.then(async (json) => {
|
.then(async (json) => {
|
||||||
data = await json.json()
|
data = await json.json()
|
||||||
admin = data?.admin ?? false
|
admin = data?.admin ?? false
|
||||||
@ -43,14 +39,25 @@
|
|||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
void fetch(`/api/v1/statistics?token=${token}`, {})
|
async function fetchUIStats (): Promise<void> {
|
||||||
|
await fetch(`/api/v1/statistics?token=${token}`, {})
|
||||||
.then(async (json) => {
|
.then(async (json) => {
|
||||||
dataFront = await json.json()
|
dataFront = await json.json()
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let data: any
|
||||||
|
let dataFront: any
|
||||||
|
let admin = false
|
||||||
|
onDestroy(
|
||||||
|
ticker.subscribe(() => {
|
||||||
|
void fetchStats()
|
||||||
|
|
||||||
|
void fetchUIStats()
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
const tabs: TabItem[] = [
|
const tabs: TabItem[] = [
|
||||||
@ -264,6 +271,24 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{:else if selectedTab === 'statistics'}
|
{:else if selectedTab === 'statistics'}
|
||||||
|
{#if admin}
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div class="flex-row-center p-1">
|
||||||
|
<div class="p-3">1.</div>
|
||||||
|
<Button
|
||||||
|
icon={IconArrowRight}
|
||||||
|
label={getEmbeddedLabel('Wipe statistics')}
|
||||||
|
on:click={() => {
|
||||||
|
void fetch(endpoint + `/api/v1/manage?token=${token}&operation=wipe-statistics`, {
|
||||||
|
method: 'PUT'
|
||||||
|
}).then(async () => {
|
||||||
|
await fetchStats()
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<div class="flex-column p-3 h-full" style:overflow="auto">
|
<div class="flex-column p-3 h-full" style:overflow="auto">
|
||||||
{#if metricsData !== undefined}
|
{#if metricsData !== undefined}
|
||||||
<MetricsInfo metrics={metricsData} />
|
<MetricsInfo metrics={metricsData} />
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
FROM node:20-alpine
|
FROM node:20
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
COPY bundle/bundle.js ./
|
COPY bundle/bundle.js ./
|
||||||
|
RUN npm install --ignore-scripts=false --verbose bufferutil utf-8-validate @mongodb-js/zstd --unsafe-perm
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
CMD [ "node", "bundle.js" ]
|
CMD [ "node", "bundle.js" ]
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
|
||||||
FROM node:20-alpine
|
FROM node:20
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
RUN npm install --ignore-scripts=false --verbose bufferutil utf-8-validate @mongodb-js/zstd --unsafe-perm
|
||||||
COPY bundle/bundle.js ./
|
COPY bundle/bundle.js ./
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
FROM node:20
|
FROM node:20
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
RUN npm install --ignore-scripts=false --verbose bufferutil --unsafe-perm
|
RUN npm install --ignore-scripts=false --verbose bufferutil utf-8-validate @mongodb-js/zstd --unsafe-perm
|
||||||
|
|
||||||
COPY bundle/bundle.js ./
|
COPY bundle/bundle.js ./
|
||||||
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
FROM node:20-alpine
|
FROM node:20
|
||||||
|
|
||||||
RUN apk add dumb-init
|
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN npm install --ignore-scripts=false --verbose sharp@v0.32.6 --unsafe-perm
|
RUN npm install --ignore-scripts=false --verbose sharp@v0.32.6 bufferutil utf-8-validate @mongodb-js/zstd --unsafe-perm
|
||||||
|
|
||||||
COPY bundle/bundle.js ./
|
COPY bundle/bundle.js ./
|
||||||
COPY dist/ ./dist/
|
COPY dist/ ./dist/
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
CMD [ "dumb-init", "node", "./bundle.js" ]
|
CMD [ "node", "./bundle.js" ]
|
||||||
|
@ -3,10 +3,9 @@ FROM node:20
|
|||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN npm install --ignore-scripts=false --verbose bufferutil --unsafe-perm
|
RUN npm install --ignore-scripts=false --verbose bufferutil utf-8-validate @mongodb-js/zstd --unsafe-perm
|
||||||
|
|
||||||
COPY bundle/bundle.js ./
|
COPY bundle/bundle.js ./
|
||||||
# COPY ./dist/*.node ./
|
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
CMD [ "node", "./bundle.js" ]
|
CMD [ "node", "./bundle.js" ]
|
||||||
|
@ -45,8 +45,7 @@ export function createRawMongoDBAdapter (url: string): RawDBAdapter {
|
|||||||
const db = getWorkspaceDB(await client.getClient(), workspace)
|
const db = getWorkspaceDB(await client.getClient(), workspace)
|
||||||
const coll = db.collection(domain)
|
const coll = db.collection(domain)
|
||||||
let cursor = coll.find<T>(query as Filter<Document>, {
|
let cursor = coll.find<T>(query as Filter<Document>, {
|
||||||
checkKeys: false,
|
checkKeys: false
|
||||||
enableUtf8Validation: false
|
|
||||||
})
|
})
|
||||||
|
|
||||||
let total: number = -1
|
let total: number = -1
|
||||||
|
@ -486,8 +486,7 @@ abstract class MongoAdapterBase implements DbAdapter {
|
|||||||
if (options?.total === true) {
|
if (options?.total === true) {
|
||||||
totalPipeline.push({ $count: 'total' })
|
totalPipeline.push({ $count: 'total' })
|
||||||
const totalCursor = this.db.collection(domain).aggregate(totalPipeline, {
|
const totalCursor = this.db.collection(domain).aggregate(totalPipeline, {
|
||||||
checkKeys: false,
|
checkKeys: false
|
||||||
enableUtf8Validation: false
|
|
||||||
})
|
})
|
||||||
const arr = await toArray(totalCursor)
|
const arr = await toArray(totalCursor)
|
||||||
total = arr?.[0]?.total ?? 0
|
total = arr?.[0]?.total ?? 0
|
||||||
@ -592,8 +591,7 @@ abstract class MongoAdapterBase implements DbAdapter {
|
|||||||
const mongoQuery = this.translateQuery(_class, query)
|
const mongoQuery = this.translateQuery(_class, query)
|
||||||
|
|
||||||
let cursor = coll.find<T>(mongoQuery, {
|
let cursor = coll.find<T>(mongoQuery, {
|
||||||
checkKeys: false,
|
checkKeys: false
|
||||||
enableUtf8Validation: false
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (options?.projection !== undefined) {
|
if (options?.projection !== undefined) {
|
||||||
@ -1252,15 +1250,19 @@ class MongoTxAdapter extends MongoAdapterBase implements TxAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getModel (ctx: MeasureContext): Promise<Tx[]> {
|
async getModel (ctx: MeasureContext): Promise<Tx[]> {
|
||||||
const modelProjection = {
|
const cursor = await ctx.with('find', {}, async () =>
|
||||||
|
this.db.collection<Tx>(DOMAIN_TX).find(
|
||||||
|
{ objectSpace: core.space.Model },
|
||||||
|
{
|
||||||
|
sort: {
|
||||||
|
_id: 1,
|
||||||
|
modifiedOn: 1
|
||||||
|
},
|
||||||
|
projection: {
|
||||||
'%hash%': 0
|
'%hash%': 0
|
||||||
}
|
}
|
||||||
const cursor = await ctx.with('find', {}, async () =>
|
}
|
||||||
this.db
|
)
|
||||||
.collection<Tx>(DOMAIN_TX)
|
|
||||||
.find({ objectSpace: core.space.Model })
|
|
||||||
.sort({ _id: 1, modifiedOn: 1 })
|
|
||||||
.project<Tx>(modelProjection)
|
|
||||||
)
|
)
|
||||||
const model = await ctx.with('to-array', {}, async () => await toArray<Tx>(cursor))
|
const model = await ctx.with('to-array', {}, async () => await toArray<Tx>(cursor))
|
||||||
// We need to put all core.account.System transactions first
|
// We need to put all core.account.System transactions first
|
||||||
|
@ -22,7 +22,7 @@ import cors from 'cors'
|
|||||||
import express from 'express'
|
import express from 'express'
|
||||||
import http, { type IncomingMessage } from 'http'
|
import http, { type IncomingMessage } from 'http'
|
||||||
import { WebSocketServer, type RawData, type WebSocket } from 'ws'
|
import { WebSocketServer, type RawData, type WebSocket } from 'ws'
|
||||||
import { getStatistics } from './stats'
|
import { getStatistics, wipeStatistics } from './stats'
|
||||||
import {
|
import {
|
||||||
LOGGING_ENABLED,
|
LOGGING_ENABLED,
|
||||||
type ConnectionSocket,
|
type ConnectionSocket,
|
||||||
@ -118,7 +118,14 @@ export function startHttpServer (
|
|||||||
|
|
||||||
res.writeHead(200)
|
res.writeHead(200)
|
||||||
res.end()
|
res.end()
|
||||||
break
|
return
|
||||||
|
}
|
||||||
|
case 'wipe-statistics': {
|
||||||
|
wipeStatistics(ctx)
|
||||||
|
|
||||||
|
res.writeHead(200)
|
||||||
|
res.end()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
case 'reboot': {
|
case 'reboot': {
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
import { type MeasureContext, metricsAggregate } from '@hcengineering/core'
|
import {
|
||||||
|
type MeasureContext,
|
||||||
|
MeasureMetricsContext,
|
||||||
|
type Metrics,
|
||||||
|
metricsAggregate,
|
||||||
|
type MetricsData
|
||||||
|
} from '@hcengineering/core'
|
||||||
import os from 'os'
|
import os from 'os'
|
||||||
import { type SessionManager } from './types'
|
import { type SessionManager } from './types'
|
||||||
|
|
||||||
@ -33,3 +39,36 @@ export function getStatistics (ctx: MeasureContext, sessions: SessionManager, ad
|
|||||||
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export function wipeStatistics (ctx: MeasureContext): void {
|
||||||
|
const toClean: (Metrics | MetricsData)[] = []
|
||||||
|
function cleanMetrics (m: Metrics | MetricsData): void {
|
||||||
|
m.operations = 0
|
||||||
|
m.value = 0
|
||||||
|
m.topResult = undefined
|
||||||
|
if ('measurements' in m) {
|
||||||
|
for (const v of Object.values(m.measurements)) {
|
||||||
|
toClean.push(v)
|
||||||
|
}
|
||||||
|
for (const v of Object.values(m.params)) {
|
||||||
|
for (const vv of Object.values(v)) {
|
||||||
|
toClean.push(vv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx instanceof MeasureMetricsContext) {
|
||||||
|
toClean.push(ctx.metrics)
|
||||||
|
while (toClean.length > 0) {
|
||||||
|
const v = toClean.shift()
|
||||||
|
if (v === undefined) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
cleanMetrics(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user