Handle broadcast in pipeline (#5732)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2024-06-05 00:05:01 +05:00 committed by GitHub
parent fd83bf34af
commit 223479ebd5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 54 additions and 9 deletions

View File

@ -51,16 +51,27 @@ export async function createPipeline (
upgrade: boolean, upgrade: boolean,
broadcast: BroadcastFunc broadcast: BroadcastFunc
): Promise<Pipeline> { ): Promise<Pipeline> {
const broadcastHandlers: BroadcastFunc[] = [broadcast]
const _broadcast: BroadcastFunc = (
tx: Tx[],
targets: string | string[] | undefined,
exclude: string[] | undefined
) => {
for (const handler of broadcastHandlers) handler(tx, targets, exclude)
}
const storage = await ctx.with( const storage = await ctx.with(
'create-server-storage', 'create-server-storage',
{}, {},
async (ctx) => async (ctx) =>
await createServerStorage(ctx, conf, { await createServerStorage(ctx, conf, {
upgrade, upgrade,
broadcast broadcast: _broadcast
}) })
) )
const pipelineResult = await PipelineImpl.create(ctx.newChild('pipeline-operations', {}), storage, constructors) const pipelineResult = await PipelineImpl.create(ctx.newChild('pipeline-operations', {}), storage, constructors)
broadcastHandlers.push((tx: Tx[], targets: string | string[] | undefined, exclude: string[] | undefined) => {
void pipelineResult.handleBroadcast(tx, targets, exclude)
})
return pipelineResult return pipelineResult
} }
@ -115,6 +126,12 @@ class PipelineImpl implements Pipeline {
} }
} }
async handleBroadcast (tx: Tx[], targets?: string | string[], exclude?: string[]): Promise<void> {
if (this.head !== undefined) {
await this.head.handleBroadcast(tx, targets, exclude)
}
}
async close (): Promise<void> { async close (): Promise<void> {
await this.storage.close() await this.storage.close()
} }

View File

@ -94,6 +94,7 @@ export interface Middleware {
query: DocumentQuery<T>, query: DocumentQuery<T>,
options?: FindOptions<T> options?: FindOptions<T>
) => Promise<FindResult<T>> ) => Promise<FindResult<T>>
handleBroadcast: HandleBroadcastFunc
searchFulltext: (ctx: SessionContext, query: SearchQuery, options: SearchOptions) => Promise<SearchResult> searchFulltext: (ctx: SessionContext, query: SearchQuery, options: SearchOptions) => Promise<SearchResult>
} }
@ -101,10 +102,11 @@ export interface Middleware {
* @public * @public
*/ */
export type BroadcastFunc = (tx: Tx[], targets?: string | string[], exclude?: string[]) => void export type BroadcastFunc = (tx: Tx[], targets?: string | string[], exclude?: string[]) => void
/** /**
* @public * @public
*/ */
export type HandledBroadcastFunc = (tx: Tx[], targets?: string[]) => Tx[] export type HandleBroadcastFunc = (tx: Tx[], targets?: string | string[], exclude?: string[]) => Promise<void>
/** /**
* @public * @public

View File

@ -49,6 +49,12 @@ export abstract class BaseMiddleware {
return await this.provideSearchFulltext(ctx, query, options) return await this.provideSearchFulltext(ctx, query, options)
} }
async handleBroadcast (tx: Tx[], targets?: string | string[], exclude?: string[]): Promise<void> {
if (this.next !== undefined) {
await this.next.handleBroadcast(tx, targets, exclude)
}
}
protected async provideTx (ctx: SessionContext, tx: Tx): Promise<TxMiddlewareResult> { protected async provideTx (ctx: SessionContext, tx: Tx): Promise<TxMiddlewareResult> {
if (this.next !== undefined) { if (this.next !== undefined) {
return await this.next.tx(ctx, tx) return await this.next.tx(ctx, tx)

View File

@ -88,6 +88,10 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
return res return res
} }
private resyncDomains (): void {
this.spaceSecurityInit = this.init(this.spaceMeasureCtx)
}
private addMemberSpace (member: Ref<Account>, space: Ref<Space>): void { private addMemberSpace (member: Ref<Account>, space: Ref<Space>): void {
const arr = this.allowedSpaces[member] ?? [] const arr = this.allowedSpaces[member] ?? []
arr.push(space) arr.push(space)
@ -393,6 +397,11 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
await this.brodcastEvent(ctx, [cud.objectId]) await this.brodcastEvent(ctx, [cud.objectId])
} }
} }
} else if (tx._class === core.class.TxWorkspaceEvent) {
const event = tx as TxWorkspaceEvent
if (event.event === WorkspaceEvent.BulkUpdate) {
this.resyncDomains()
}
} }
} }
@ -414,16 +423,27 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
it.target = mergeTargets(targets, it.target) it.target = mergeTargets(targets, it.target)
}) })
await this.waitInit() return res
for (const tt of ctx.derived) {
for (const t of tt.derived) {
if (this.storage.hierarchy.isDerived(t._class, core.class.TxCUD)) {
await this.processTxSpaceDomain(t as TxCUD<Doc>)
}
}
} }
return res override async handleBroadcast (
txes: Tx[],
targets?: string | string[] | undefined,
exclude?: string[] | undefined
): Promise<void> {
for (const tx of txes) {
const h = this.storage.hierarchy
if (h.isDerived(tx._class, core.class.TxCUD)) {
const cudTx = tx as TxCUD<Doc>
await this.processTxSpaceDomain(cudTx)
} else if (tx._class === core.class.TxWorkspaceEvent) {
const event = tx as TxWorkspaceEvent
if (event.event === WorkspaceEvent.BulkUpdate) {
this.resyncDomains()
}
}
}
await this.next?.handleBroadcast(txes, targets, exclude)
} }
private getAllAllowedSpaces (account: Account, isData: boolean): Ref<Space>[] { private getAllAllowedSpaces (account: Account, isData: boolean): Ref<Space>[] {