Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions meteor/__mocks__/defaultCollectionObjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ export function defaultRundownPlaylist(_id: RundownPlaylistId, studioId: StudioI
type: 'none' as any,
},
rundownIdsInOrder: [],
tTimers: [
{ index: 1, label: '', mode: null },
{ index: 2, label: '', mode: null },
{ index: 3, label: '', mode: null },
],
}
}
export function defaultRundown(
Expand Down
1 change: 1 addition & 0 deletions meteor/server/__tests__/cronjobs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ describe('cronjobs', () => {
type: PlaylistTimingType.None,
},
activationId: protectString(''),
tTimers: [] as any,
})

return {
Expand Down
25 changes: 9 additions & 16 deletions meteor/server/api/__tests__/cleanup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ async function setDefaultDatatoDB(env: DefaultEnvironment, now: number) {
startSegmentId: segmentId,
timelineObjectsString: '' as any,
}
const pieceId = await Pieces.mutableCollection.insertAsync(piece)
await Pieces.mutableCollection.insertAsync(piece)

await AdLibActions.mutableCollection.insertAsync({
_id: getRandomId(),
Expand Down Expand Up @@ -265,22 +265,15 @@ async function setDefaultDatatoDB(env: DefaultEnvironment, now: number) {
})
const packageId = await ExpectedPackages.mutableCollection.insertAsync({
_id: getRandomId(),
blueprintPackageId: '',
// @ts-expect-error bucketId is not a part of all ExpectedPackageDBs
bucketId,
content: {} as any,
contentVersionHash: '',
created: 0,
fromPieceType: '' as any,
layers: [],
pieceId,
rundownId,
segmentId,
sideEffect: {} as any,
studioId,
sources: {} as any,
type: '' as any,
version: {} as any,
rundownId,
bucketId: null,
created: 0,
package: {} as any,
ingestSources: [],
playoutSources: {
pieceInstanceIds: [],
},
})
await ExpectedPackageWorkStatuses.insertAsync({
_id: getRandomId(),
Expand Down
1 change: 1 addition & 0 deletions meteor/server/api/__tests__/externalMessageQueue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ describe('Test external message queue static methods', () => {
type: PlaylistTimingType.None,
},
rundownIdsInOrder: [protectString('rundown_1')],
tTimers: [] as any,
})
await Rundowns.mutableCollection.insertAsync({
_id: protectString('rundown_1'),
Expand Down
1 change: 1 addition & 0 deletions meteor/server/api/__tests__/peripheralDevice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
type: PlaylistTimingType.None,
},
rundownIdsInOrder: [rundownID],
tTimers: [] as any,
})
await Rundowns.mutableCollection.insertAsync({
_id: rundownID,
Expand Down Expand Up @@ -494,7 +495,7 @@
).rejects.toThrowMeteor(418, `Error thrown, as requested`)
})

/*

Check warning on line 498 in meteor/server/api/__tests__/peripheralDevice.test.ts

View workflow job for this annotation

GitHub Actions / Typecheck and Lint Core

Some tests seem to be commented

Check warning on line 498 in meteor/server/api/__tests__/peripheralDevice.test.ts

View workflow job for this annotation

GitHub Actions / Typecheck and Lint Core

Some tests seem to be commented
test('timelineTriggerTime', () => {
if (DEBUG) setLogLevel(LogLevel.DEBUG)
let timelineTriggerTimeResult: PeripheralDeviceAPI.TimelineTriggerTimeResult = [
Expand Down Expand Up @@ -562,7 +563,7 @@
})

// Note: this test fails, due to a backwards-compatibility hack in #c579c8f0
// test('initialize with bad arguments', () => {

Check warning on line 566 in meteor/server/api/__tests__/peripheralDevice.test.ts

View workflow job for this annotation

GitHub Actions / Typecheck and Lint Core

Some tests seem to be commented

Check warning on line 566 in meteor/server/api/__tests__/peripheralDevice.test.ts

View workflow job for this annotation

GitHub Actions / Typecheck and Lint Core

Some tests seem to be commented
// let options: PeripheralDeviceInitOptions = {
// category: PeripheralDeviceCategory.INGEST,
// type: PeripheralDeviceType.MOS,
Expand All @@ -583,7 +584,7 @@
// }
// })

// test('setStatus with bad arguments', () => {

Check warning on line 587 in meteor/server/api/__tests__/peripheralDevice.test.ts

View workflow job for this annotation

GitHub Actions / Typecheck and Lint Core

Some tests seem to be commented

Check warning on line 587 in meteor/server/api/__tests__/peripheralDevice.test.ts

View workflow job for this annotation

GitHub Actions / Typecheck and Lint Core

Some tests seem to be commented
// try {
// Meteor.call(PeripheralDeviceAPIMethods.setStatus, 'wibbly', device.token, { statusCode: 0 })
// fail('expected to throw')
Expand Down
28 changes: 0 additions & 28 deletions meteor/server/api/ingest/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { QueueStudioJob } from '../../worker/worker'
import { StudioJobs } from '@sofie-automation/corelib/dist/worker/studio'
import { RundownPlaylistId, SegmentId } from '@sofie-automation/corelib/dist/dataModel/Ids'
import { MeteorDebugMethods } from '../../methods'
import { DBRundown } from '@sofie-automation/corelib/dist/dataModel/Rundown'

MeteorDebugMethods({
/**
Expand Down Expand Up @@ -47,31 +46,4 @@ MeteorDebugMethods({
segmentExternalId: segment.externalId,
})
},
/**
* Regenerate all the expected packages for all rundowns in the system.
* Additionally it will recreate any expectedPlayoutItems.
* This shouldn't be necessary as ingest will do this for each rundown as part of its workflow
*/
debug_recreateExpectedPackages: async () => {
const rundowns = (await Rundowns.findFetchAsync(
{},
{
projection: {
_id: 1,
studioId: 1,
source: 1,
},
}
)) as Array<Pick<DBRundown, '_id' | 'studioId' | 'source'>>

await Promise.all(
rundowns
.filter((rundown) => rundown.source.type !== 'snapshot')
.map(async (rundown) =>
runIngestOperation(rundown.studioId, IngestJobs.ExpectedPackagesRegenerate, {
rundownId: rundown._id,
})
)
)
},
})
65 changes: 37 additions & 28 deletions meteor/server/api/ingest/packageInfo.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import {
ExpectedPackageDBFromBucketAdLib,
ExpectedPackageDBFromBucketAdLibAction,
ExpectedPackageDBFromStudioBaselineObjects,
ExpectedPackageDBType,
ExpectedPackageFromRundown,
ExpectedPackageFromRundownBaseline,
ExpectedPackageDB,
ExpectedPackageIngestSourceBucket,
} from '@sofie-automation/corelib/dist/dataModel/ExpectedPackages'
import { PackageInfoDB } from '@sofie-automation/corelib/dist/dataModel/PackageInfos'
import { ExpectedPackages, Rundowns } from '../../collections'
Expand All @@ -28,8 +25,10 @@ export async function onUpdatedPackageInfo(packageId: ExpectedPackageId, _doc: P
return
}

if (pkg.listenToPackageInfoUpdates) {
switch (pkg.fromPieceType) {
for (const source of pkg.ingestSources) {
if (!source.listenToPackageInfoUpdates) continue

switch (source.fromPieceType) {
case ExpectedPackageDBType.PIECE:
case ExpectedPackageDBType.ADLIB_PIECE:
case ExpectedPackageDBType.ADLIB_ACTION:
Expand All @@ -41,39 +40,44 @@ export async function onUpdatedPackageInfo(packageId: ExpectedPackageId, _doc: P
break
case ExpectedPackageDBType.BUCKET_ADLIB:
case ExpectedPackageDBType.BUCKET_ADLIB_ACTION:
onUpdatedPackageInfoForBucketItemDebounce(pkg)
onUpdatedPackageInfoForBucketItemDebounce(pkg, source)
break
case ExpectedPackageDBType.STUDIO_BASELINE_OBJECTS:
onUpdatedPackageInfoForStudioBaselineDebounce(pkg)
break
default:
assertNever(pkg)
assertNever(source)
break
}
}
}

const pendingRundownPackageUpdates = new Map<RundownId, Array<ExpectedPackageId>>()
function onUpdatedPackageInfoForRundownDebounce(pkg: ExpectedPackageFromRundown | ExpectedPackageFromRundownBaseline) {
const existingEntry = pendingRundownPackageUpdates.get(pkg.rundownId)
function onUpdatedPackageInfoForRundownDebounce(pkg: ExpectedPackageDB) {
if (!pkg.rundownId) {
logger.error(`Updating ExpectedPackage "${pkg._id}" not possibe: missing rundownId`)
return
}

const rundownId = pkg.rundownId

const existingEntry = pendingRundownPackageUpdates.get(rundownId)
if (existingEntry) {
// already queued, add to the batch
existingEntry.push(pkg._id)
} else {
pendingRundownPackageUpdates.set(pkg.rundownId, [pkg._id])
pendingRundownPackageUpdates.set(rundownId, [pkg._id])
}

// TODO: Scaling - this won't batch correctly if package manager directs calls to multiple instances
lazyIgnore(
`onUpdatedPackageInfoForRundown_${pkg.rundownId}`,
`onUpdatedPackageInfoForRundown_${rundownId}`,
() => {
const packageIds = pendingRundownPackageUpdates.get(pkg.rundownId)
const packageIds = pendingRundownPackageUpdates.get(rundownId)
if (packageIds) {
pendingRundownPackageUpdates.delete(pkg.rundownId)
onUpdatedPackageInfoForRundown(pkg.rundownId, packageIds).catch((e) => {
logger.error(
`Updating ExpectedPackages for Rundown "${pkg.rundownId}" failed: ${stringifyError(e)}`
)
pendingRundownPackageUpdates.delete(rundownId)
onUpdatedPackageInfoForRundown(rundownId, packageIds).catch((e) => {
logger.error(`Updating ExpectedPackages for Rundown "${rundownId}" failed: ${stringifyError(e)}`)
})
}
},
Expand Down Expand Up @@ -108,19 +112,24 @@ async function onUpdatedPackageInfoForRundown(
})
}

function onUpdatedPackageInfoForBucketItemDebounce(
pkg: ExpectedPackageDBFromBucketAdLib | ExpectedPackageDBFromBucketAdLibAction
) {
function onUpdatedPackageInfoForBucketItemDebounce(pkg: ExpectedPackageDB, source: ExpectedPackageIngestSourceBucket) {
if (!pkg.bucketId) {
logger.error(`Updating ExpectedPackage "${pkg._id}" for Bucket "${pkg.bucketId}" not possible`)
return
}

const bucketId = pkg.bucketId

lazyIgnore(
`onUpdatedPackageInfoForBucket_${pkg.studioId}_${pkg.bucketId}_${pkg.pieceExternalId}`,
`onUpdatedPackageInfoForBucket_${pkg.studioId}_${bucketId}_${source.pieceExternalId}`,
() => {
runIngestOperation(pkg.studioId, IngestJobs.BucketItemRegenerate, {
bucketId: pkg.bucketId,
externalId: pkg.pieceExternalId,
bucketId: bucketId,
externalId: source.pieceExternalId,
}).catch((err) => {
logger.error(
`Updating ExpectedPackages for Bucket "${pkg.bucketId}" Item "${
pkg.pieceExternalId
`Updating ExpectedPackages for Bucket "${bucketId}" Item "${
source.pieceExternalId
}" failed: ${stringifyError(err)}`
)
})
Expand All @@ -129,7 +138,7 @@ function onUpdatedPackageInfoForBucketItemDebounce(
)
}

function onUpdatedPackageInfoForStudioBaselineDebounce(pkg: ExpectedPackageDBFromStudioBaselineObjects) {
function onUpdatedPackageInfoForStudioBaselineDebounce(pkg: ExpectedPackageDB) {
lazyIgnore(
`onUpdatedPackageInfoForStudioBaseline_${pkg.studioId}`,
() => {
Expand Down
15 changes: 12 additions & 3 deletions meteor/server/api/integration/expectedPackages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
} from '../../collections'
import { logger } from '../../logging'
import _ from 'underscore'
import { ExpectedPackageDB } from '@sofie-automation/corelib/dist/dataModel/ExpectedPackages'

export namespace PackageManagerIntegration {
export async function updateExpectedPackageWorkStatuses(
Expand Down Expand Up @@ -99,9 +100,17 @@ export namespace PackageManagerIntegration {
const fromPackageIds = workStatus.fromPackages.map((p) => p.id)
if (fromPackageIds.length) {
ps.push(
ExpectedPackages.findOneAsync({
_id: { $in: fromPackageIds },
}).then((expPackage) => {
ExpectedPackages.findOneAsync(
{
_id: { $in: fromPackageIds },
},
{
projection: {
_id: 1,
studioId: 1,
},
}
).then((expPackage: Pick<ExpectedPackageDB, '_id' | 'studioId'> | undefined) => {
if (!expPackage)
throw new Meteor.Error(404, `ExpectedPackages "${fromPackageIds}" not found`)

Expand Down
8 changes: 5 additions & 3 deletions meteor/server/collections/packages-media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ export const ExpectedPackages = createAsyncOnlyReadOnlyMongoCollection<ExpectedP
)
registerIndex(ExpectedPackages, {
studioId: 1,
fromPieceType: 1,
})
registerIndex(ExpectedPackages, {
studioId: 1,
pieceId: 1,
rundownId: 1,
})
registerIndex(ExpectedPackages, {
studioId: 1,
bucketId: 1,
})
registerIndex(ExpectedPackages, {
rundownId: 1,
pieceId: 1,
})

export const ExpectedPackageWorkStatuses = createAsyncOnlyMongoCollection<ExpectedPackageWorkStatus>(
Expand Down
12 changes: 6 additions & 6 deletions meteor/server/migration/1_50_0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import { JSONBlobStringify, JSONSchema, TSR } from '@sofie-automation/blueprints
import { DEFAULT_MINIMUM_TAKE_SPAN } from '@sofie-automation/shared-lib/dist/core/constants'
import { PartId } from '@sofie-automation/shared-lib/dist/core/model/Ids'
import { protectString } from '@sofie-automation/shared-lib/dist/lib/protectedString'
import { ExpectedPackageDBType } from '@sofie-automation/corelib/dist/dataModel/ExpectedPackages'
import {
AdLibActionId,
BucketAdLibActionId,
Expand All @@ -44,6 +43,7 @@ import {
import { Piece } from '@sofie-automation/corelib/dist/dataModel/Piece'
import { AdLibPiece } from '@sofie-automation/corelib/dist/dataModel/AdLibPiece'
import { AdLibAction } from '@sofie-automation/corelib/dist/dataModel/AdlibAction'
import * as PackagesPreR53 from '@sofie-automation/corelib/dist/dataModel/Old/ExpectedPackagesR52'

// Release 50

Expand Down Expand Up @@ -161,9 +161,9 @@ const oldDeviceTypeToNewMapping = {
}

const EXPECTED_PACKAGE_TYPES_ADDED_PART_ID = [
ExpectedPackageDBType.PIECE,
ExpectedPackageDBType.ADLIB_PIECE,
ExpectedPackageDBType.ADLIB_ACTION,
PackagesPreR53.ExpectedPackageDBType.PIECE,
PackagesPreR53.ExpectedPackageDBType.ADLIB_PIECE,
PackagesPreR53.ExpectedPackageDBType.ADLIB_ACTION,
]

export const addSteps = addMigrationSteps('1.50.0', [
Expand Down Expand Up @@ -875,10 +875,10 @@ export const addSteps = addMigrationSteps('1.50.0', [
return false
},
migrate: async () => {
const objects = await ExpectedPackages.findFetchAsync({
const objects = (await ExpectedPackages.findFetchAsync({
fromPieceType: { $in: EXPECTED_PACKAGE_TYPES_ADDED_PART_ID as any }, // Force the types, as the query does not match due to the interfaces
partId: { $exists: false },
})
})) as unknown as Array<PackagesPreR53.ExpectedPackageDB>

const neededPieceIds: Array<
PieceId | AdLibActionId | RundownBaselineAdLibActionId | BucketAdLibId | BucketAdLibActionId
Expand Down
Loading
Loading