feat: add tracing

This commit is contained in:
Eric Maciel 2021-02-11 16:28:51 -05:00
parent 2681254c7a
commit e3ce984941

View File

@ -3,10 +3,24 @@ import * as Automerge from 'automerge'
import { Node } from 'slate' import { Node } from 'slate'
import { Server } from 'http' import { Server } from 'http'
import throttle from 'lodash/throttle' import throttle from 'lodash/throttle'
import flatten from 'lodash/flatten'
import { SyncDoc, CollabAction, toJS } from '@hiveteams/collab-bridge' import { SyncDoc, CollabAction, toJS } from '@hiveteams/collab-bridge'
import { debugCollabBackend } from './utils/debug' import { debugCollabBackend } from './utils/debug'
import AutomergeBackend from './AutomergeBackend' import AutomergeBackend from './AutomergeBackend'
export interface IAutomergeMetaData {
docId: string
userId: string
type: string
opText?: string
opCount?: number
}
export type ITraceFunction = (
metaData: IAutomergeMetaData,
computationFunction: () => void
) => void
export interface IAutomergeCollaborationOptions { export interface IAutomergeCollaborationOptions {
entry: Server entry: Server
connectOpts?: SocketIO.ServerOptions connectOpts?: SocketIO.ServerOptions
@ -21,6 +35,11 @@ export interface IAutomergeCollaborationOptions {
) => Promise<void> | void ) => Promise<void> | void
onDisconnect?: (docId: string, user: any) => Promise<void> | void onDisconnect?: (docId: string, user: any) => Promise<void> | void
onError?: (error: Error, data: any) => Promise<void> | void onError?: (error: Error, data: any) => Promise<void> | void
onTrace?: ITraceFunction
}
const defaultOnTrace: ITraceFunction = (metaData, computation) => {
computation()
} }
export default class AutomergeCollaboration { export default class AutomergeCollaboration {
@ -29,6 +48,7 @@ export default class AutomergeCollaboration {
public backend: AutomergeBackend public backend: AutomergeBackend
private userMap: { [key: string]: any | undefined } private userMap: { [key: string]: any | undefined }
private autoSaveDoc: (socket: SocketIO.Socket, docId: string) => void private autoSaveDoc: (socket: SocketIO.Socket, docId: string) => void
private onTrace: ITraceFunction
/** /**
* Constructor * Constructor
@ -45,6 +65,8 @@ export default class AutomergeCollaboration {
this.userMap = {} this.userMap = {}
this.onTrace = options.onTrace || defaultOnTrace
/** /**
* Save document with throttle * Save document with throttle
*/ */
@ -182,12 +204,21 @@ export default class AutomergeCollaboration {
return return
} }
const user = this.userMap[id]
const metaData: IAutomergeMetaData = {
type: 'connect',
userId: user?._id,
docId
}
this.onTrace(metaData, () => {
// Emit the socket message needed for receiving the automerge document // Emit the socket message needed for receiving the automerge document
// on connect and reconnect // on connect and reconnect
socket.emit('msg', { socket.emit('msg', {
type: 'document', type: 'document',
payload: Automerge.save<SyncDoc>(doc) payload: Automerge.save<SyncDoc>(doc)
}) })
})
debugCollabBackend('Open connection %s', id) debugCollabBackend('Open connection %s', id)
this.backend.openConnection(id) this.backend.openConnection(id)
@ -205,6 +236,24 @@ export default class AutomergeCollaboration {
data: any data: any
) => { ) => {
const { id } = socket const { id } = socket
const user = this.userMap[id]
// parse out the changes contained in this automerge change
const collabActions = flatten(
data.payload.changes?.map((change: Automerge.Change) =>
change.ops.map(op => op.action)
)
)
const metaData: IAutomergeMetaData = {
type: 'operation',
userId: user?._id,
docId,
// cap max operation text by 1000 chars
opText: collabActions.join(',').slice(0, 1000),
opCount: collabActions.length
}
this.onTrace(metaData, () => {
switch (data.type) { switch (data.type) {
case 'operation': case 'operation':
try { try {
@ -217,6 +266,7 @@ export default class AutomergeCollaboration {
this.handleError(socket, err, { onMessageData: data }) this.handleError(socket, err, { onMessageData: data })
} }
} }
})
} }
/** /**