mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-13 03:40:48 +00:00
UBERF-8547 Do not update collaborative doc in platform when content not changed (#7115)
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
This commit is contained in:
parent
aa4eaeae84
commit
afa485deb1
@ -14,7 +14,7 @@
|
||||
//
|
||||
|
||||
import { DocumentId } from '@hcengineering/collaborator-client'
|
||||
import { MeasureContext } from '@hcengineering/core'
|
||||
import { type Markup, MeasureContext } from '@hcengineering/core'
|
||||
import {
|
||||
Document,
|
||||
Extension,
|
||||
@ -37,19 +37,35 @@ export interface StorageConfiguration {
|
||||
transformer: Transformer
|
||||
}
|
||||
|
||||
type DocumentName = string
|
||||
|
||||
type ConnectionId = string
|
||||
|
||||
interface DocumentUpdates {
|
||||
context: Context
|
||||
collaborators: Set<ConnectionId>
|
||||
}
|
||||
|
||||
export class StorageExtension implements Extension {
|
||||
private readonly configuration: StorageConfiguration
|
||||
private readonly collaborators = new Map<string, Set<string>>()
|
||||
private readonly markups = new Map<string, Record<string, string>>()
|
||||
private readonly updates = new Map<DocumentName, DocumentUpdates>()
|
||||
private readonly markups = new Map<DocumentName, Record<Markup, Markup>>()
|
||||
|
||||
constructor (configuration: StorageConfiguration) {
|
||||
this.configuration = configuration
|
||||
}
|
||||
|
||||
async onChange ({ context, documentName }: withContext<onChangePayload>): Promise<any> {
|
||||
const collaborators = this.collaborators.get(documentName) ?? new Set()
|
||||
collaborators.add(context.connectionId)
|
||||
this.collaborators.set(documentName, collaborators)
|
||||
const { connectionId } = context
|
||||
|
||||
const updates = this.updates.get(documentName)
|
||||
if (updates === undefined) {
|
||||
const collaborators = new Set([connectionId])
|
||||
this.updates.set(documentName, { context, collaborators })
|
||||
} else {
|
||||
updates.context = context
|
||||
updates.collaborators.add(connectionId)
|
||||
}
|
||||
}
|
||||
|
||||
async onLoadDocument ({ context, documentName }: withContext<onLoadDocumentPayload>): Promise<any> {
|
||||
@ -59,7 +75,7 @@ export class StorageExtension implements Extension {
|
||||
return await this.loadDocument(documentName, context)
|
||||
}
|
||||
|
||||
async afterLoadDocument ({ context, documentName, document }: withContext<afterLoadDocumentPayload>): Promise<any> {
|
||||
async afterLoadDocument ({ documentName, document }: withContext<afterLoadDocumentPayload>): Promise<any> {
|
||||
// remember the markup for the document
|
||||
this.markups.set(documentName, this.configuration.transformer.fromYdoc(document))
|
||||
}
|
||||
@ -70,14 +86,14 @@ export class StorageExtension implements Extension {
|
||||
|
||||
ctx.info('store document', { documentName, connectionId })
|
||||
|
||||
const collaborators = this.collaborators.get(documentName)
|
||||
if (collaborators === undefined || collaborators.size === 0) {
|
||||
const updates = this.updates.get(documentName)
|
||||
if (updates === undefined || updates.collaborators.size === 0) {
|
||||
ctx.info('no changes for document', { documentName, connectionId })
|
||||
return
|
||||
}
|
||||
|
||||
this.collaborators.delete(documentName)
|
||||
await this.storeDocument(documentName, document, context)
|
||||
this.updates.delete(documentName)
|
||||
await this.storeDocument(documentName, document, updates.context)
|
||||
}
|
||||
|
||||
async onConnect ({ context, documentName, instance }: withContext<onConnectPayload>): Promise<any> {
|
||||
@ -93,19 +109,19 @@ export class StorageExtension implements Extension {
|
||||
const params = { documentName, connectionId, connections: document.getConnectionsCount() }
|
||||
ctx.info('disconnect from document', params)
|
||||
|
||||
const collaborators = this.collaborators.get(documentName)
|
||||
if (collaborators === undefined || !collaborators.has(connectionId)) {
|
||||
const updates = this.updates.get(documentName)
|
||||
if (updates === undefined || updates.collaborators.size === 0) {
|
||||
ctx.info('no changes for document', { documentName, connectionId })
|
||||
return
|
||||
}
|
||||
|
||||
this.collaborators.delete(documentName)
|
||||
this.updates.delete(documentName)
|
||||
await this.storeDocument(documentName, document, context)
|
||||
}
|
||||
|
||||
async afterUnloadDocument ({ documentName }: afterUnloadDocumentPayload): Promise<any> {
|
||||
this.configuration.ctx.info('unload document', { documentName })
|
||||
this.collaborators.delete(documentName)
|
||||
this.updates.delete(documentName)
|
||||
this.markups.delete(documentName)
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ export async function updateContent (
|
||||
fragment.delete(0, fragment.length)
|
||||
applyUpdate(document, update)
|
||||
})
|
||||
})
|
||||
}, connection)
|
||||
})
|
||||
})
|
||||
} finally {
|
||||
|
@ -34,6 +34,7 @@ import { Doc as YDoc } from 'yjs'
|
||||
import { Context } from '../context'
|
||||
|
||||
import { CollabStorageAdapter } from './adapter'
|
||||
import { areEqualMarkups } from '@hcengineering/text'
|
||||
|
||||
export class PlatformStorageAdapter implements CollabStorageAdapter {
|
||||
constructor (private readonly storage: StorageAdapter) {}
|
||||
@ -156,6 +157,14 @@ export class PlatformStorageAdapter implements CollabStorageAdapter {
|
||||
): Promise<void> {
|
||||
const { objectClass, objectId, objectAttr } = parsePlatformDocumentId(platformDocumentId)
|
||||
|
||||
const currMarkup = markup.curr[objectAttr]
|
||||
const prevMarkup = markup.prev[objectAttr]
|
||||
|
||||
if (areEqualMarkups(currMarkup, prevMarkup)) {
|
||||
ctx.info('markup not changed, skip platform update', { documentName })
|
||||
return
|
||||
}
|
||||
|
||||
const attribute = client.getHierarchy().findAttribute(objectClass, objectAttr)
|
||||
if (attribute === undefined) {
|
||||
ctx.warn('attribute not found', { documentName, objectClass, objectAttr })
|
||||
@ -192,8 +201,8 @@ export class PlatformStorageAdapter implements CollabStorageAdapter {
|
||||
attributeUpdates: {
|
||||
attrKey: objectAttr,
|
||||
attrClass: core.class.TypeMarkup,
|
||||
prevValue: markup.prev[objectAttr],
|
||||
set: [markup.curr[objectAttr]],
|
||||
prevValue: prevMarkup,
|
||||
set: [currMarkup],
|
||||
added: [],
|
||||
removed: [],
|
||||
isMixin: hierarchy.isMixin(objectClass)
|
||||
|
Loading…
Reference in New Issue
Block a user