@@ -43,6 +43,7 @@ import { DBPart } from '@sofie-automation/corelib/dist/dataModel/Part'
43
43
import { DatabasePersistedModel } from '../modelBase'
44
44
import { updateSegmentIdsForAdlibbedPartInstances } from './commit/updateSegmentIdsForAdlibbedPartInstances'
45
45
import { stringifyError } from '@sofie-automation/shared-lib/dist/lib/stringifyError'
46
+ import { AnyBulkWriteOperation } from 'mongodb'
46
47
47
48
export type BeforePartMapItem = { id : PartId ; rank : number }
48
49
export type BeforeIngestOperationPartMap = ReadonlyMap < SegmentId , Array < BeforePartMapItem > >
@@ -301,26 +302,32 @@ async function updatePartInstancesSegmentIds(
301
302
renamedSegments : ReadonlyMap < SegmentId , SegmentId > | null ,
302
303
beforePartMap : BeforeIngestOperationPartMap
303
304
) {
304
- // A set of rules which can be translated to mongo queries for PartInstances to update
305
+ /**
306
+ * Maps new SegmentId ->
307
+ * A set of rules which can be translated to mongo queries for PartInstances to update
308
+ */
305
309
const renameRules = new Map <
306
310
SegmentId ,
307
311
{
312
+ /** Parts that have been moved to the new SegmentId */
308
313
partIds : PartId [ ]
309
- fromSegmentId : SegmentId | null
314
+ /** Segments that have been renamed to the new SegmentId */
315
+ fromSegmentIds : SegmentId [ ]
310
316
}
311
317
> ( )
312
318
313
319
// Add whole segment renames to the set of rules
314
320
if ( renamedSegments ) {
315
321
for ( const [ fromSegmentId , toSegmentId ] of renamedSegments ) {
316
- const rule = renameRules . get ( toSegmentId ) ?? { partIds : [ ] , fromSegmentId : null }
322
+ const rule = renameRules . get ( toSegmentId ) ?? { partIds : [ ] , fromSegmentIds : [ ] }
317
323
renameRules . set ( toSegmentId , rule )
318
324
319
- rule . fromSegmentId = fromSegmentId
325
+ rule . fromSegmentIds . push ( fromSegmentId )
320
326
}
321
327
}
322
328
323
- // Reverse the structure
329
+ // Reverse the Map structure
330
+ /** Maps Part -> SegmentId-of-the-part-before-ingest-changes */
324
331
const beforePartSegmentIdMap = new Map < PartId , SegmentId > ( )
325
332
for ( const [ segmentId , partItems ] of beforePartMap . entries ( ) ) {
326
333
for ( const partItem of partItems ) {
@@ -331,8 +338,11 @@ async function updatePartInstancesSegmentIds(
331
338
// Some parts may have gotten a different segmentId to the base rule, so track those seperately in the rules
332
339
for ( const partModel of ingestModel . getAllOrderedParts ( ) ) {
333
340
const oldSegmentId = beforePartSegmentIdMap . get ( partModel . part . _id )
341
+
334
342
if ( oldSegmentId && oldSegmentId !== partModel . part . segmentId ) {
335
- const rule = renameRules . get ( partModel . part . segmentId ) ?? { partIds : [ ] , fromSegmentId : null }
343
+ // The part has moved to another segment, add a rule to update its corresponding PartInstances:
344
+
345
+ const rule = renameRules . get ( partModel . part . segmentId ) ?? { partIds : [ ] , fromSegmentIds : [ ] }
336
346
renameRules . set ( partModel . part . segmentId , rule )
337
347
338
348
rule . partIds . push ( partModel . part . _id )
@@ -341,30 +351,52 @@ async function updatePartInstancesSegmentIds(
341
351
342
352
// Perform a mongo update to modify the PartInstances
343
353
if ( renameRules . size > 0 ) {
344
- await context . directCollections . PartInstances . bulkWrite (
345
- Array . from ( renameRules . entries ( ) ) . map ( ( [ newSegmentId , rule ] ) => ( {
346
- updateMany : {
347
- filter : {
348
- $or : _ . compact ( [
349
- rule . fromSegmentId
350
- ? {
351
- segmentId : rule . fromSegmentId ,
352
- }
353
- : undefined ,
354
- {
355
- 'part._id' : { $in : rule . partIds } ,
354
+ const rulesInOrder = Array . from ( renameRules . entries ( ) ) . sort ( ( a , b ) => {
355
+ // Ensure that the ones with partIds are processed last,
356
+ // as that should take precedence.
357
+
358
+ if ( a [ 1 ] . partIds . length && ! b [ 1 ] . partIds . length ) return 1
359
+ if ( ! a [ 1 ] . partIds . length && b [ 1 ] . partIds . length ) return - 1
360
+ return 0
361
+ } )
362
+
363
+ const writeOps : AnyBulkWriteOperation < DBPartInstance > [ ] = [ ]
364
+
365
+ for ( const [ newSegmentId , rule ] of rulesInOrder ) {
366
+ if ( rule . fromSegmentIds . length ) {
367
+ writeOps . push ( {
368
+ updateMany : {
369
+ filter : {
370
+ rundownId : ingestModel . rundownId ,
371
+ segmentId : { $in : rule . fromSegmentIds } ,
372
+ } ,
373
+ update : {
374
+ $set : {
375
+ segmentId : newSegmentId ,
376
+ 'part.segmentId' : newSegmentId ,
356
377
} ,
357
- ] ) ,
378
+ } ,
358
379
} ,
359
- update : {
360
- $set : {
361
- segmentId : newSegmentId ,
362
- 'part.segmentId' : newSegmentId ,
380
+ } )
381
+ }
382
+ if ( rule . partIds . length ) {
383
+ writeOps . push ( {
384
+ updateMany : {
385
+ filter : {
386
+ rundownId : ingestModel . rundownId ,
387
+ 'part._id' : { $in : rule . partIds } ,
388
+ } ,
389
+ update : {
390
+ $set : {
391
+ segmentId : newSegmentId ,
392
+ 'part.segmentId' : newSegmentId ,
393
+ } ,
363
394
} ,
364
395
} ,
365
- } ,
366
- } ) )
367
- )
396
+ } )
397
+ }
398
+ }
399
+ if ( writeOps . length ) await context . directCollections . PartInstances . bulkWrite ( writeOps )
368
400
}
369
401
}
370
402
@@ -691,8 +723,10 @@ async function removeSegments(
691
723
for ( const segment of ingestModel . getAllSegments ( ) ) {
692
724
const segmentId = segment . segment . _id
693
725
if ( segment . segment . isHidden ) {
726
+ // Blueprints want to hide the Segment
727
+
694
728
if ( ! canRemoveSegment ( previousPartInstance , currentPartInstance , nextPartInstance , segmentId ) ) {
695
- // Protect live segment from being hidden
729
+ // The Segment is live, so we need to protect it from being hidden
696
730
logger . warn ( `Cannot hide live segment ${ segmentId } , it will be orphaned` )
697
731
switch ( segment . segment . orphaned ) {
698
732
case SegmentOrphanedReason . DELETED :
0 commit comments