Skip to content

Commit ba69857

Browse files
committed
Merge branch 'release51'
2 parents a7deec9 + baacf0e commit ba69857

File tree

29 files changed

+239
-92
lines changed

29 files changed

+239
-92
lines changed

meteor/CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
### [1.51.6](///compare/v1.51.5...v1.51.6) (2025-01-14)
6+
7+
8+
### Features
9+
10+
* add more logging 8c16ce8
11+
12+
13+
### Bug Fixes
14+
15+
* Include previousPartInstance in check to orphan segments rather than remove them. 51b7104
16+
* only run onPart/PiecePlaybackStarted/Stopped on current, next or previous parts a9fe401
17+
* **PoGw:** filter log output to ensure that message field in JSONL output is never an object 0d2b844
18+
* set nextPartInstance to null if it's referring to a Segment that has been removed b1045f9
19+
* updatePartInstancesSegmentIds: take into account when multiple segments have been merged into one. b769157
20+
521
### [1.51.5](///compare/v1.51.4...v1.51.5) (2025-01-07)
622

723

meteor/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "automation-core",
3-
"version": "1.51.5",
3+
"version": "1.51.6",
44
"private": true,
55
"engines": {
66
"node": ">=14.19.1"

meteor/yarn.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,7 @@ __metadata:
13211321
version: 0.0.0-use.local
13221322
resolution: "@sofie-automation/blueprints-integration@portal:../packages/blueprints-integration::locator=automation-core%40workspace%3A."
13231323
dependencies:
1324-
"@sofie-automation/shared-lib": 1.51.5
1324+
"@sofie-automation/shared-lib": 1.51.6
13251325
tslib: ^2.6.2
13261326
type-fest: ^3.13.1
13271327
languageName: node
@@ -1362,8 +1362,8 @@ __metadata:
13621362
version: 0.0.0-use.local
13631363
resolution: "@sofie-automation/corelib@portal:../packages/corelib::locator=automation-core%40workspace%3A."
13641364
dependencies:
1365-
"@sofie-automation/blueprints-integration": 1.51.5
1366-
"@sofie-automation/shared-lib": 1.51.5
1365+
"@sofie-automation/blueprints-integration": 1.51.6
1366+
"@sofie-automation/shared-lib": 1.51.6
13671367
fast-clone: ^1.5.13
13681368
i18next: ^21.10.0
13691369
influx: ^5.9.3
@@ -1394,9 +1394,9 @@ __metadata:
13941394
resolution: "@sofie-automation/job-worker@portal:../packages/job-worker::locator=automation-core%40workspace%3A."
13951395
dependencies:
13961396
"@slack/webhook": ^6.1.0
1397-
"@sofie-automation/blueprints-integration": 1.51.5
1398-
"@sofie-automation/corelib": 1.51.5
1399-
"@sofie-automation/shared-lib": 1.51.5
1397+
"@sofie-automation/blueprints-integration": 1.51.6
1398+
"@sofie-automation/corelib": 1.51.6
1399+
"@sofie-automation/shared-lib": 1.51.6
14001400
amqplib: ^0.10.3
14011401
deepmerge: ^4.3.1
14021402
elastic-apm-node: ^3.51.0

packages/blueprints-integration/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [1.51.6](https://github.com/nrkno/sofie-core/compare/v1.51.5...v1.51.6) (2025-01-14)
7+
8+
**Note:** Version bump only for package @sofie-automation/blueprints-integration
9+
10+
11+
12+
13+
614
## [1.51.5](https://github.com/nrkno/sofie-core/compare/v1.51.4...v1.51.5) (2025-01-07)
715

816
**Note:** Version bump only for package @sofie-automation/blueprints-integration

packages/blueprints-integration/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sofie-automation/blueprints-integration",
3-
"version": "1.51.5",
3+
"version": "1.51.6",
44
"description": "Library to define the interaction between core and the blueprints.",
55
"main": "dist/index.js",
66
"typings": "dist/index.d.ts",
@@ -38,7 +38,7 @@
3838
"/LICENSE"
3939
],
4040
"dependencies": {
41-
"@sofie-automation/shared-lib": "1.51.5",
41+
"@sofie-automation/shared-lib": "1.51.6",
4242
"tslib": "^2.6.2",
4343
"type-fest": "^3.13.1"
4444
},

packages/corelib/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sofie-automation/corelib",
3-
"version": "1.51.5",
3+
"version": "1.51.6",
44
"private": true,
55
"description": "Internal library for some types shared by core and workers",
66
"main": "dist/index.js",
@@ -39,8 +39,8 @@
3939
"/LICENSE"
4040
],
4141
"dependencies": {
42-
"@sofie-automation/blueprints-integration": "1.51.5",
43-
"@sofie-automation/shared-lib": "1.51.5",
42+
"@sofie-automation/blueprints-integration": "1.51.6",
43+
"@sofie-automation/shared-lib": "1.51.6",
4444
"fast-clone": "^1.5.13",
4545
"i18next": "^21.10.0",
4646
"influx": "^5.9.3",

packages/documentation/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sofie-documentation",
3-
"version": "1.51.5",
3+
"version": "1.51.6",
44
"private": true,
55
"scripts": {
66
"docusaurus": "docusaurus",

packages/job-worker/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sofie-automation/job-worker",
3-
"version": "1.51.5",
3+
"version": "1.51.6",
44
"description": "Worker for things",
55
"main": "dist/index.js",
66
"license": "MIT",
@@ -41,9 +41,9 @@
4141
],
4242
"dependencies": {
4343
"@slack/webhook": "^6.1.0",
44-
"@sofie-automation/blueprints-integration": "1.51.5",
45-
"@sofie-automation/corelib": "1.51.5",
46-
"@sofie-automation/shared-lib": "1.51.5",
44+
"@sofie-automation/blueprints-integration": "1.51.6",
45+
"@sofie-automation/corelib": "1.51.6",
46+
"@sofie-automation/shared-lib": "1.51.6",
4747
"amqplib": "^0.10.3",
4848
"deepmerge": "^4.3.1",
4949
"elastic-apm-node": "^3.51.0",

packages/job-worker/src/ingest/commit.ts

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,13 @@ export async function CommitIngestOperation(
178178
// Ensure any adlibbed parts are updated to follow the segmentId of the previous part
179179
await updateSegmentIdsForAdlibbedPartInstances(context, ingestModel, beforePartMap)
180180

181+
// TODO: This whole section can probably be removed later, it's really unneccessary in the grand scheme of
182+
// things, it's here only to debug some problems
181183
if (data.renamedSegments && data.renamedSegments.size > 0) {
182-
logger.debug(`Renamed segments: ${JSON.stringify(Array.from(data.renamedSegments.entries()))}`)
184+
logger.verbose(`Renamed segments: ${JSON.stringify(Array.from(data.renamedSegments.entries()))}`)
183185
}
186+
// End of temporary section
187+
184188
// ensure instances have matching segmentIds with the parts
185189
await updatePartInstancesSegmentIds(context, ingestModel, data.renamedSegments, beforePartMap)
186190

@@ -220,6 +224,8 @@ export async function CommitIngestOperation(
220224
const pSaveIngest = ingestModel.saveAllToDatabase()
221225
pSaveIngest.catch(() => null) // Ensure promise isn't reported as unhandled
222226

227+
ensureNextPartInstanceIsNotDeleted(playoutModel)
228+
223229
await validateAdlibTestingSegment(context, playoutModel)
224230

225231
try {
@@ -273,14 +279,18 @@ function canRemoveSegment(
273279
logger.warn(`Not allowing removal of previous playing segment "${segmentId}", making segment unsynced instead`)
274280
return false
275281
}
276-
if (
277-
currentPartInstance?.segmentId === segmentId ||
278-
(nextPartInstance?.segmentId === segmentId && isTooCloseToAutonext(currentPartInstance, false))
279-
) {
282+
if (currentPartInstance?.segmentId === segmentId) {
280283
// Don't allow removing an active rundown
281284
logger.warn(`Not allowing removal of current playing segment "${segmentId}", making segment unsynced instead`)
282285
return false
283286
}
287+
if (nextPartInstance?.segmentId === segmentId && isTooCloseToAutonext(currentPartInstance, false)) {
288+
// Don't allow removing an active rundown
289+
logger.warn(
290+
`Not allowing removal of nexted segment "${segmentId}", because it's too close to an auto-next, making segment unsynced instead`
291+
)
292+
return false
293+
}
284294

285295
if (nextPartInstance?.segmentId === segmentId && nextPartInstance.orphaned === 'adlib-part') {
286296
// Don't allow removing an active rundown
@@ -365,6 +375,8 @@ async function updatePartInstancesSegmentIds(
365375

366376
const writeOps: AnyBulkWriteOperation<DBPartInstance>[] = []
367377

378+
logger.debug(`updatePartInstancesSegmentIds: renameRules: ${JSON.stringify(renameRules)}`)
379+
368380
for (const [newSegmentId, rule] of rulesInOrder) {
369381
if (rule.fromSegmentIds.length) {
370382
writeOps.push({
@@ -402,32 +414,24 @@ async function updatePartInstancesSegmentIds(
402414
if (writeOps.length) await context.directCollections.PartInstances.bulkWrite(writeOps)
403415

404416
// Double check that there are no parts using the old segment ids:
405-
const oldSegmentIds = Array.from(renameRules.keys())
406-
const [badPartInstances, badParts] = await Promise.all([
407-
await context.directCollections.PartInstances.findFetch({
408-
rundownId: ingestModel.rundownId,
409-
segmentId: { $in: oldSegmentIds },
410-
}),
411-
await context.directCollections.Parts.findFetch({
412-
rundownId: ingestModel.rundownId,
413-
segmentId: { $in: oldSegmentIds },
414-
}),
415-
])
417+
// TODO: This whole section can probably be removed later, it's really unneccessary in the grand scheme of
418+
// things, it's here only to debug some problems
419+
const oldSegmentIds: SegmentId[] = []
420+
for (const renameRule of renameRules.values()) {
421+
oldSegmentIds.push(...renameRule.fromSegmentIds)
422+
}
423+
const badPartInstances = await context.directCollections.PartInstances.findFetch({
424+
rundownId: ingestModel.rundownId,
425+
segmentId: { $in: oldSegmentIds },
426+
})
416427
if (badPartInstances.length > 0) {
417428
logger.error(
418429
`updatePartInstancesSegmentIds: Failed to update all PartInstances using old SegmentIds "${JSON.stringify(
419430
oldSegmentIds
420431
)}": ${JSON.stringify(badPartInstances)}, writeOps: ${JSON.stringify(writeOps)}`
421432
)
422433
}
423-
424-
if (badParts.length > 0) {
425-
logger.error(
426-
`updatePartInstancesSegmentIds: Failed to update all Parts using old SegmentIds "${JSON.stringify(
427-
oldSegmentIds
428-
)}": ${JSON.stringify(badParts)}, writeOps: ${JSON.stringify(writeOps)}`
429-
)
430-
}
434+
// End of the temporary section
431435
}
432436
}
433437

@@ -662,10 +666,27 @@ async function getSelectedPartInstances(
662666
})
663667
: []
664668

669+
const currentPartInstance = instances.find((inst) => inst._id === playlist.currentPartInfo?.partInstanceId)
670+
const nextPartInstance = instances.find((inst) => inst._id === playlist.nextPartInfo?.partInstanceId)
671+
const previousPartInstance = instances.find((inst) => inst._id === playlist.previousPartInfo?.partInstanceId)
672+
673+
if (playlist.currentPartInfo?.partInstanceId && !currentPartInstance)
674+
logger.error(
675+
`playlist.currentPartInfo is set, but PartInstance "${playlist.currentPartInfo?.partInstanceId}" was not found!`
676+
)
677+
if (playlist.nextPartInfo?.partInstanceId && !nextPartInstance)
678+
logger.error(
679+
`playlist.nextPartInfo is set, but PartInstance "${playlist.nextPartInfo?.partInstanceId}" was not found!`
680+
)
681+
if (playlist.previousPartInfo?.partInstanceId && !previousPartInstance)
682+
logger.error(
683+
`playlist.previousPartInfo is set, but PartInstance "${playlist.previousPartInfo?.partInstanceId}" was not found!`
684+
)
685+
665686
return {
666-
currentPartInstance: instances.find((inst) => inst._id === playlist.currentPartInfo?.partInstanceId),
667-
nextPartInstance: instances.find((inst) => inst._id === playlist.nextPartInfo?.partInstanceId),
668-
previousPartInstance: instances.find((inst) => inst._id === playlist.previousPartInfo?.partInstanceId),
687+
currentPartInstance,
688+
nextPartInstance,
689+
previousPartInstance,
669690
}
670691
}
671692

@@ -815,6 +836,16 @@ async function removeSegments(
815836
})
816837
}
817838
for (const segmentId of purgeSegmentIds) {
839+
logger.debug(
840+
`IngestModel: Removing segment "${segmentId}" (` +
841+
`previousPartInfo?.partInstanceId: ${newPlaylist.previousPartInfo?.partInstanceId},` +
842+
`currentPartInfo?.partInstanceId: ${newPlaylist.currentPartInfo?.partInstanceId},` +
843+
`nextPartInfo?.partInstanceId: ${newPlaylist.nextPartInfo?.partInstanceId},` +
844+
`previousPartInstance.segmentId: ${!previousPartInstance ? 'N/A' : previousPartInstance.segmentId},` +
845+
`currentPartInstance.segmentId: ${!currentPartInstance ? 'N/A' : currentPartInstance.segmentId},` +
846+
`nextPartInstance.segmentId: ${!nextPartInstance ? 'N/A' : nextPartInstance.segmentId}` +
847+
`)`
848+
)
818849
ingestModel.removeSegment(segmentId)
819850
}
820851
}
@@ -824,3 +855,12 @@ async function validateAdlibTestingSegment(_context: JobContext, playoutModel: P
824855
rundown.updateAdlibTestingSegmentRank()
825856
}
826857
}
858+
function ensureNextPartInstanceIsNotDeleted(playoutModel: PlayoutModel) {
859+
if (playoutModel.nextPartInstance) {
860+
// Check if the segment of the nextPartInstance exists
861+
if (!playoutModel.findSegment(playoutModel.nextPartInstance.partInstance.segmentId)) {
862+
// The segment doesn't exist, set nextPartInstance to null, it'll be set by ensureNextPartIsValid() later.
863+
playoutModel.setPartInstanceAsNext(null, false, false)
864+
}
865+
}
866+
}

packages/job-worker/src/ingest/lock.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ export interface CommitIngestData {
2222
removedSegmentIds: SegmentId[]
2323
/**
2424
* Segments that had their ids changed. This helps then be orphaned in the correct place
25-
* eg, whole segment is renamed and middle part deleted
26-
* Note: Only supported for MOS, not 'normal' ingest operations
25+
* eg, whole segment is renamed and middle part deleted.
26+
*
27+
* Maps fromSegmentId to toSegmentId.
28+
*
29+
* _Note: Only supported for MOS, not 'normal' ingest operations_
2730
*/
2831
renamedSegments: Map<SegmentId, SegmentId> | null
2932

0 commit comments

Comments
 (0)