Skip to content

Commit

Permalink
feat: subscribe to separated core collections SOFIE-1926
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Jun 27, 2023
1 parent b759978 commit 281e579
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 84 deletions.
4 changes: 3 additions & 1 deletion apps/package-manager/packages/generic/src/coreHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,10 @@ export class CoreHandler {
this.logger.info('DeviceId: ' + this.core.deviceId)
await Promise.all([
this.core.autoSubscribe('peripheralDeviceForDevice', this.core.deviceId),
this.core.autoSubscribe('expectedPackagesForDevice', this.core.deviceId, undefined),
this.core.autoSubscribe('peripheralDeviceCommands', this.core.deviceId),
this.core.autoSubscribe('packageManagerPlayoutContext', this.core.deviceId),
this.core.autoSubscribe('packageManagerPackageContainers', this.core.deviceId),
this.core.autoSubscribe('packageManagerExpectedPackages', this.core.deviceId, undefined),
])

this.logger.info('Core: Subscriptions are set up!')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import { ActivePlaylist, ActiveRundown, ExpectedPackageWrap, PackageContainers } from '../packageManager'
import { ExpectedPackageWrap, PackageContainers } from '../packageManager'
import { PackageManagerSettings } from '../generated/options'
import { Expectation, LoggerInstance, PackageContainerExpectation } from '@sofie-package-manager/api'
import {
PackageManagerActivePlaylist,
PackageManagerActiveRundown,
// eslint-disable-next-line node/no-extraneous-import
} from '@sofie-automation/shared-lib/dist/package-manager/publications'

export interface GenerateExpectationApi {
getExpectations: (
logger: LoggerInstance,
managerId: string,
packageContainers: PackageContainers,
_activePlaylist: ActivePlaylist,
activeRundowns: ActiveRundown[],
_activePlaylist: PackageManagerActivePlaylist | null,
activeRundowns: PackageManagerActiveRundown[],
expectedPackages: ExpectedPackageWrap[],
settings: PackageManagerSettings
) => { [id: string]: Expectation.Any }

getPackageContainerExpectations: (
managerId: string,
packageContainers: PackageContainers,
_activePlaylist: ActivePlaylist
_activePlaylist: PackageManagerActivePlaylist | null
) => { [id: string]: PackageContainerExpectation }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ActivePlaylist, ActiveRundown, ExpectedPackageWrap, PackageContainers } from '../../packageManager'
import { ExpectedPackageWrap, PackageContainers } from '../../packageManager'
import { PackageManagerSettings } from '../../generated/options'
import { ExpectedPackage, PackageContainer, Expectation, hashObj, LoggerInstance } from '@sofie-package-manager/api'
import { GenerateExpectation, PriorityMagnitude } from './types'
Expand All @@ -19,14 +19,21 @@ import {
} from './expectations-lib'
import { getSmartbullExpectedPackages, shouldBeIgnored } from './smartbull'
import { TEMPORARY_STORAGE_ID } from './lib'
import {
PackageManagerActivePlaylist,
PackageManagerActiveRundown,
// eslint-disable-next-line node/no-extraneous-import
} from '@sofie-automation/shared-lib/dist/package-manager/publications'
// eslint-disable-next-line node/no-extraneous-import
import { RundownId } from '@sofie-automation/shared-lib/dist/core/model/Ids'

/** Generate and return the appropriate Expectations based on the provided expectedPackages */
export function getExpectations(
logger: LoggerInstance,
managerId: string,
packageContainers: PackageContainers,
_activePlaylist: ActivePlaylist,
activeRundowns: ActiveRundown[],
_activePlaylist: PackageManagerActivePlaylist | null,
activeRundowns: PackageManagerActiveRundown[],
expectedPackages: ExpectedPackageWrap[],
settings: PackageManagerSettings
): { [id: string]: Expectation.Any } {
Expand All @@ -46,7 +53,7 @@ export function getExpectations(
return 0
})
// Prepare:
const activeRundownMap = new Map<string, ActiveRundown>()
const activeRundownMap = new Map<RundownId, PackageManagerActiveRundown>()
for (const activeRundown of activeRundowns) {
activeRundownMap.set(activeRundown._id, activeRundown)
}
Expand Down Expand Up @@ -353,7 +360,7 @@ function getCopyToTemporaryStorage(

function addExpectation(
logger: LoggerInstance,
activeRundownMap: Map<string, ActiveRundown>,
activeRundownMap: Map<RundownId, PackageManagerActiveRundown>,
expectations: ExpectationCollection,
packageWrap: ExpectedPackageWrap,
exp: Expectation.Any
Expand Down Expand Up @@ -391,13 +398,13 @@ function addExpectation(
}
/** Returns a priority for an expectation. */
function getPriority(
activeRundownMap: Map<string, ActiveRundown>,
activeRundownMap: Map<RundownId, PackageManagerActiveRundown>,
packageWrap: ExpectedPackageWrap,
exp: Expectation.Any
): number {
// Returns the initial priority, based on the expectedPackage

const activeRundown: ActiveRundown | undefined = packageWrap.expectedPackage.rundownId
const activeRundown: PackageManagerActiveRundown | undefined = packageWrap.expectedPackage.rundownId
? activeRundownMap.get(packageWrap.expectedPackage.rundownId)
: undefined

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { ActivePlaylist, PackageContainers } from '../../packageManager'
import { PackageContainers } from '../../packageManager'
import { PackageContainerExpectation } from '@sofie-package-manager/api'
import { SMARTBULL_STORAGE_ID, TEMPORARY_STORAGE_ID } from './lib'
// eslint-disable-next-line node/no-extraneous-import
import { PackageManagerActivePlaylist } from '@sofie-automation/shared-lib/dist/package-manager/publications'

// Max age for untracked files
const MAX_FILE_AGE = 30 * 24 * 3600 // 30 days

export function getPackageContainerExpectations(
managerId: string,
packageContainers: PackageContainers,
_activePlaylist: ActivePlaylist
_activePlaylist: PackageManagerActivePlaylist | null
): { [id: string]: PackageContainerExpectation } {
const o: { [id: string]: PackageContainerExpectation } = {}

Expand Down
133 changes: 65 additions & 68 deletions apps/package-manager/packages/generic/src/packageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,24 @@ import _ from 'underscore'
import { CoreHandler } from './coreHandler'
// eslint-disable-next-line node/no-extraneous-import
import { ExpectedPackageStatusAPI } from '@sofie-automation/shared-lib/dist/package-manager/package'
import { protectString, protectStringArray } from '@sofie-automation/server-core-integration'
import {
PackageManagerActivePlaylist,
PackageManagerActiveRundown,
PackageManagerExpectedPackage,
PackageManagerExpectedPackageBase,
PackageManagerPackageContainers,
PackageManagerPlayoutContext,
// eslint-disable-next-line node/no-extraneous-import
} from '@sofie-automation/shared-lib/dist/package-manager/publications'
import {
Observer,
PeripheralDeviceId,
protectString,
protectStringArray,
} from '@sofie-automation/server-core-integration'
// eslint-disable-next-line node/no-extraneous-import
import { UpdateExpectedPackageWorkStatusesChanges } from '@sofie-automation/shared-lib/dist/peripheralDevice/methodsAPI'
// eslint-disable-next-line node/no-extraneous-import
import {
ExpectationManager,
ExpectationManagerCallbacks,
Expand Down Expand Up @@ -51,7 +66,7 @@ export class PackageManagerHandler {
}
private _triggerUpdatedExpectedPackagesTimeout: NodeJS.Timeout | null = null
public monitoredPackages: {
[monitorId: string]: ResultingExpectedPackage[]
[monitorId: string]: ExpectedPackageWrap[]
} = {}
settings: PackageManagerSettings = {
delayRemoval: 0,
Expand All @@ -61,7 +76,7 @@ export class PackageManagerHandler {

private dataSnapshot: {
updated: number
expectedPackages: ResultingExpectedPackage[]
expectedPackages: ExpectedPackageWrap[]
packageContainers: PackageContainers
expectations: {
[id: string]: Expectation.Any
Expand Down Expand Up @@ -169,17 +184,25 @@ export class PackageManagerHandler {
if (this.coreHandler.notUsingCore) return // Abort if we are not using core
this.logger.debug('Renewing observers')

const expectedPackagesObserver = this.coreHandler.observe('deviceExpectedPackages')
expectedPackagesObserver.added = () => {
this.triggerUpdatedExpectedPackages()
}
expectedPackagesObserver.changed = () => {
this.triggerUpdatedExpectedPackages()
}
expectedPackagesObserver.removed = () => {
this.triggerUpdatedExpectedPackages()
const triggerUpdateOnAnyChange = (observer: Observer) => {
observer.added = () => {
this.triggerUpdatedExpectedPackages()
}
observer.changed = () => {
this.triggerUpdatedExpectedPackages()
}
observer.removed = () => {
this.triggerUpdatedExpectedPackages()
}
this._observers.push(observer)
}
this._observers.push(expectedPackagesObserver)

const expectedPackagesObserver = this.coreHandler.observe('deviceExpectedPackages')
triggerUpdateOnAnyChange(expectedPackagesObserver)

triggerUpdateOnAnyChange(this.coreHandler.observe('packageManagerPlayoutContext'))
triggerUpdateOnAnyChange(this.coreHandler.observe('packageManagerPackageContainers'))
triggerUpdateOnAnyChange(this.coreHandler.observe('packageManagerExpectedPackages'))
}
public triggerUpdatedExpectedPackages(): void {
if (this._triggerUpdatedExpectedPackagesTimeout) {
Expand All @@ -193,12 +216,8 @@ export class PackageManagerHandler {
const expectedPackages: ExpectedPackageWrap[] = []
const packageContainers: PackageContainers = {}

let activePlaylist: ActivePlaylist = {
_id: '',
active: false,
rehearsal: false,
}
let activeRundowns: ActiveRundown[] = []
let activePlaylist: PackageManagerActivePlaylist | null = null
let activeRundowns: PackageManagerActiveRundown[] = []

// Add from external data:
{
Expand All @@ -209,41 +228,32 @@ export class PackageManagerHandler {
}

if (!this.coreHandler.notUsingCore) {
const objs = this.coreHandler.getCollection<any>('deviceExpectedPackages').find(() => true)
const playoutContextObj = this.coreHandler
.getCollection<PackageManagerPlayoutContext>('packageManagerPlayoutContext')
.find()[0]
if (playoutContextObj) {
activePlaylist = playoutContextObj.activePlaylist
activeRundowns = playoutContextObj.activeRundowns
} else {
this.logger.warn(`packageManagerPlayoutContext collection object not found`)
return
}

const activePlaylistObj = objs.find((o) => o.type === 'active_playlist')
if (!activePlaylistObj) {
this.logger.warn(`Collection objects active_playlist not found`)
this.logger.info(`objs in deviceExpectedPackages:`, objs)
const packageContainersObj = this.coreHandler
.getCollection<PackageManagerPackageContainers>('packageManagerPackageContainers')
.find()[0]
if (packageContainersObj) {
Object.assign(packageContainers, packageContainersObj.packageContainers)
} else {
this.logger.warn(`packageManagerPackageContainers collection object not found`)
return
}
activePlaylist = activePlaylistObj.activeplaylist as ActivePlaylist
activeRundowns = activePlaylistObj.activeRundowns as ActiveRundown[]

// Add from Core collections:
{
const expectedPackageObjs = objs.filter((o) => o.type === 'expected_packages')

if (!expectedPackageObjs.length) {
this.logger.warn(`Collection objects expected_packages not found`)
this.logger.info(`objs in deviceExpectedPackages:`, objs)
return
}
for (const expectedPackageObj of expectedPackageObjs) {
for (const expectedPackage of expectedPackageObj.expectedPackages) {
// Note: There might be duplicates of packages here, to be deduplicated later
expectedPackages.push(expectedPackage)
}
}

const packageContainerObj = objs.find((o) => o.type === 'package_containers')
if (!packageContainerObj) {
this.logger.warn(`Collection objects package_containers not found`)
this.logger.info(`objs in deviceExpectedPackages:`, objs)
return
}
Object.assign(packageContainers, packageContainerObj.packageContainers as PackageContainers)
}
const expectedPackagesObjs = this.coreHandler
.getCollection<PackageManagerExpectedPackage>('packageManagerExpectedPackages')
.find()
expectedPackages.push(...expectedPackagesObjs)
}

// Add from Monitors:
Expand All @@ -261,8 +271,8 @@ export class PackageManagerHandler {

private handleExpectedPackages(
packageContainers: PackageContainers,
activePlaylist: ActivePlaylist,
activeRundowns: ActiveRundown[],
activePlaylist: PackageManagerActivePlaylist | null,
activeRundowns: PackageManagerActiveRundown[],

expectedPackages: ExpectedPackageWrap[]
) {
Expand Down Expand Up @@ -1011,7 +1021,7 @@ export function wrapExpectedPackage(
priority: 999, // Default: lowest priority
sources: combinedSources,
targets: combinedTargets,
playoutDeviceId: '',
playoutDeviceId: null,
external: true,
}
}
Expand Down Expand Up @@ -1041,33 +1051,20 @@ export function deleteAllUndefinedProperties<T extends { [key: string]: any }>(o
}
}

interface ResultingExpectedPackage {
// This interface is copied from Core

expectedPackage: ExpectedPackage.Base & { rundownId?: string }
export interface ExpectedPackageWrap {
expectedPackage: PackageManagerExpectedPackageBase
/** Lower should be done first */
priority: number
sources: PackageContainerOnPackage[]
targets: PackageContainerOnPackage[]
playoutDeviceId: string
playoutDeviceId: PeripheralDeviceId | null
/** If set to true, this doesn't come from Core */
external?: boolean
// playoutLocation: any // todo?
}
export type ExpectedPackageWrap = ResultingExpectedPackage

export type PackageContainers = { [containerId: string]: PackageContainer }

export interface ActivePlaylist {
_id: string
active: boolean
rehearsal: boolean
}
export interface ActiveRundown {
_id: string
_rank: number
}

type ReportStatuses<Status, Ids> = {
[key: string]: ReportStatus<Status, Ids>
}
Expand Down
7 changes: 5 additions & 2 deletions shared/packages/api/src/inputApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,18 @@ export namespace ExpectedPackage {
/** The sideEffect is used by the Package Manager to generate extra artifacts, such as thumbnails & previews */
sideEffect: {
/** Which container previews are to be put into */
previewContainerId?: string | null
previewContainerId?: string | null // null is used to disable the sideEffect
previewPackageSettings?: SideEffectPreviewSettings | null

/** Which container thumbnails are to be put into */
thumbnailContainerId?: string | null
thumbnailContainerId?: string | null // null is used to disable the sideEffect
thumbnailPackageSettings?: SideEffectThumbnailSettings | null

/** Should the package be scanned for loudness */
loudnessPackageSettings?: SideEffectLoudnessSettings

/** Other custom configuration */
[key: string]: any
}
}
export interface SideEffectPreviewSettings {
Expand Down

0 comments on commit 281e579

Please sign in to comment.