Skip to content

Commit

Permalink
Add logger
Browse files Browse the repository at this point in the history
  • Loading branch information
wkozyra95 committed Dec 18, 2024
1 parent e620c11 commit 8da2701
Show file tree
Hide file tree
Showing 29 changed files with 518 additions and 87 deletions.
14 changes: 9 additions & 5 deletions compositor_web/src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,23 @@ mod wgpu;
pub fn start() -> Result<(), JsValue> {
console_error_panic_hook::set_once();
tracing_wasm::set_as_global_default();
wasm_log::init(wasm_log::Config::new(log::Level::Info));

Ok(())
}

#[wasm_bindgen]
pub async fn create_renderer(options: JsValue) -> Result<LiveCompositorRenderer, JsValue> {
let options = types::from_js_value::<types::RendererOptions>(options)?;
// This option will only be respected for the first renderer
let _ = wasm_log::try_init(wasm_log::Config::new(options.logger_level.into()));

let (device, queue) = create_wgpu_context().await?;
let mut options: compositor_render::RendererOptions =
types::from_js_value::<types::RendererOptions>(options)?.into();
options.wgpu_ctx = Some((device, queue));

let (renderer, _) = Renderer::new(options).map_err(to_js_error)?;
let (renderer, _) = Renderer::new(compositor_render::RendererOptions {
wgpu_ctx: Some((device, queue)),
..options.into()
})
.map_err(to_js_error)?;
let input_uploader = InputUploader::default();
let output_downloader = OutputDownloader::default();

Expand Down
25 changes: 24 additions & 1 deletion compositor_web/src/wasm/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,30 @@ use wasm_bindgen::prelude::*;

#[derive(Debug, Deserialize)]
pub struct RendererOptions {
stream_fallback_timeout_ms: u64,
pub stream_fallback_timeout_ms: u64,
pub logger_level: LoggerLevel,
}

#[derive(Debug, Deserialize, Clone, Copy)]
#[serde(rename_all = "snake_case")]
pub enum LoggerLevel {
Error,
Warn,
Info,
Debug,
Trace,
}

impl From<LoggerLevel> for log::Level {
fn from(value: LoggerLevel) -> Self {
match value {
LoggerLevel::Error => log::Level::Error,
LoggerLevel::Warn => log::Level::Warn,
LoggerLevel::Info => log::Level::Info,
LoggerLevel::Debug => log::Level::Debug,
LoggerLevel::Trace => log::Level::Trace,
}
}
}

#[wasm_bindgen]
Expand Down
3 changes: 3 additions & 0 deletions ts/@live-compositor/browser-render/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export type RendererOptions = {
* A timeout that defines when the compositor should switch to fallback on the input stream that stopped sending frames.
*/
streamFallbackTimeoutMs: number;

logger_level?: 'error' | 'warn' | 'info' | 'debug' | 'trace';
};

export type FrameSet = {
Expand Down Expand Up @@ -34,6 +36,7 @@ export class Renderer {
public static async create(options: RendererOptions): Promise<Renderer> {
const renderer = await wasm.create_renderer({
stream_fallback_timeout_ms: options.streamFallbackTimeoutMs,
logger_level: options.logger_level ?? 'warn',
});
return new Renderer(renderer);
}
Expand Down
5 changes: 3 additions & 2 deletions ts/@live-compositor/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@
"@types/react-reconciler": "0.28.8"
},
"dependencies": {
"pino": "^9.5.0",
"react-reconciler": "0.29.2"
},
"peerDependencies": {
"react": "*",
"live-compositor": "workspace:^0.1.0"
"live-compositor": "workspace:^0.1.0",
"react": "*"
}
}
3 changes: 3 additions & 0 deletions ts/@live-compositor/core/src/compositorManager.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import type { Logger } from 'pino';
import type { ApiRequest } from './api.js';

export interface SetupInstanceOptions {
/**
* sets LIVE_COMPOSITOR_AHEAD_OF_TIME_PROCESSING_ENABLE environment variable.
*/
aheadOfTimeProcessing: boolean;

logger: Logger;
}

export interface CompositorManager {
Expand Down
7 changes: 4 additions & 3 deletions ts/@live-compositor/core/src/event.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { _liveCompositorInternals } from 'live-compositor';
import { parseInputRef } from './api/input.js';
import type { Logger } from 'pino';

export type CompositorEvent = _liveCompositorInternals.CompositorEvent;
export const CompositorEventType = _liveCompositorInternals.CompositorEventType;

export function parseEvent(event: any): CompositorEvent | null {
export function parseEvent(event: any, logger: Logger): CompositorEvent | null {
if (!event.type) {
console.error(`Malformed event: ${event}`);
logger.error(`Malformed event: ${event}`);
return null;
} else if (
[
Expand All @@ -22,7 +23,7 @@ export function parseEvent(event: any): CompositorEvent | null {
} else if (CompositorEventType.OUTPUT_DONE === event.type) {
return { type: event.type, outputId: event.output_id };
} else {
console.error(`Unknown event type: ${event.type}`);
logger.error(`Unknown event type: ${event.type}`);
return null;
}
}
1 change: 1 addition & 0 deletions ts/@live-compositor/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export { OfflineCompositor } from './offline/compositor.js';
export { CompositorManager, SetupInstanceOptions } from './compositorManager.js';
export { RegisterInputRequest, RegisterInput } from './api/input.js';
export { RegisterOutputRequest, RegisterOutput } from './api/output.js';
export { Logger, LoggerLevel } from './logger.js';
36 changes: 31 additions & 5 deletions ts/@live-compositor/core/src/live/compositor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,46 @@ import { parseEvent } from '../event.js';
import { intoRegisterImage, intoRegisterWebRenderer } from '../api/renderer.js';
import { handleEvent } from './event.js';
import type { ReactElement } from 'react';
import type { Logger } from 'pino';

export class LiveCompositor {
private manager: CompositorManager;
private api: ApiClient;
private store: _liveCompositorInternals.LiveInputStreamStore<string>;
private outputs: Record<string, Output> = {};
private startTime?: number;
private logger: Logger;

public constructor(manager: CompositorManager) {
public constructor(manager: CompositorManager, logger: Logger) {
this.manager = manager;
this.api = new ApiClient(this.manager);
this.store = new _liveCompositorInternals.LiveInputStreamStore();
this.store = new _liveCompositorInternals.LiveInputStreamStore(logger);
this.logger = logger;
}

public async init(): Promise<void> {
this.manager.registerEventListener((event: unknown) => this.handleEvent(event));
await this.manager.setupInstance({ aheadOfTimeProcessing: false });
await this.manager.setupInstance({
aheadOfTimeProcessing: false,
logger: this.logger.child({ element: 'connection-manager' }),
});
}

public async registerOutput(
outputId: string,
root: ReactElement,
request: RegisterOutput
): Promise<object> {
const output = new Output(outputId, root, request, this.api, this.store, this.startTime);
this.logger.info({ outputId, type: request.type }, 'Register new output');
const output = new Output(
outputId,
root,
request,
this.api,
this.store,
this.startTime,
this.logger
);

const apiRequest = intoRegisterOutput(request, output.scene());
const result = await this.api.registerOutput(outputId, apiRequest);
Expand All @@ -45,13 +60,15 @@ export class LiveCompositor {
}

public async unregisterOutput(outputId: string): Promise<object> {
this.logger.info({ outputId }, 'Unregister output');
this.outputs[outputId].close();
delete this.outputs[outputId];
// TODO: wait for event
return this.api.unregisterOutput(outputId, {});
}

public async registerInput(inputId: string, request: RegisterInput): Promise<object> {
this.logger.info({ inputId, type: request.type }, 'Register new input');
return this.store.runBlocking(async updateStore => {
const inputRef = { type: 'global', id: inputId } as const;
const result = await this.api.registerInput(inputRef, intoRegisterInput(request));
Expand All @@ -68,6 +85,7 @@ export class LiveCompositor {
}

public async unregisterInput(inputId: string): Promise<object> {
this.logger.info({ inputId }, 'Unregister input');
return this.store.runBlocking(async updateStore => {
const inputRef = { type: 'global', id: inputId } as const;
const result = this.api.unregisterInput(inputRef, {});
Expand All @@ -80,33 +98,40 @@ export class LiveCompositor {
shaderId: string,
request: Renderers.RegisterShader
): Promise<object> {
this.logger.info({ shaderId }, 'Register shader');
return this.api.registerShader(shaderId, request);
}

public async unregisterShader(shaderId: string): Promise<object> {
this.logger.info({ shaderId }, 'Unregister shader');
return this.api.unregisterShader(shaderId);
}

public async registerImage(imageId: string, request: Renderers.RegisterImage): Promise<object> {
this.logger.info({ imageId }, 'Register image');
return this.api.registerImage(imageId, intoRegisterImage(request));
}

public async unregisterImage(imageId: string): Promise<object> {
this.logger.info({ imageId }, 'Unregister image');
return this.api.unregisterImage(imageId);
}

public async registerWebRenderer(
instanceId: string,
request: Renderers.RegisterWebRenderer
): Promise<object> {
this.logger.info({ instanceId }, 'Register web renderer');
return this.api.registerWebRenderer(instanceId, intoRegisterWebRenderer(request));
}

public async unregisterWebRenderer(instanceId: string): Promise<object> {
this.logger.info({ instanceId }, 'Unregister web renderer');
return this.api.unregisterWebRenderer(instanceId);
}

public async start(): Promise<void> {
this.logger.info('Start compositor instance.');
const startTime = Date.now();
await this.api.start();
Object.values(this.outputs).forEach(output => {
Expand All @@ -116,10 +141,11 @@ export class LiveCompositor {
}

private handleEvent(rawEvent: unknown) {
const event = parseEvent(rawEvent);
const event = parseEvent(rawEvent, this.logger);
if (!event) {
return;
}
this.logger.debug({ event }, 'New event received');
handleEvent(this.store, this.outputs, event);
}
}
24 changes: 19 additions & 5 deletions ts/@live-compositor/core/src/live/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { RegisterOutput } from '../api/output.js';
import { intoAudioInputsConfiguration } from '../api/output.js';
import { throttle } from '../utils.js';
import { OutputRootComponent, OutputShutdownStateStore } from '../rootComponent.js';
import type { Logger } from 'pino';

type AudioContext = _liveCompositorInternals.AudioContext;
type LiveTimeContext = _liveCompositorInternals.LiveTimeContext;
Expand All @@ -21,6 +22,7 @@ class Output {
timeContext: LiveTimeContext;
internalInputStreamStore: LiveInputStreamStore<number>;
outputShutdownStateStore: OutputShutdownStateStore;
logger: Logger;

shouldUpdateWhenReady: boolean = false;
throttledUpdate: () => void;
Expand All @@ -36,9 +38,11 @@ class Output {
registerRequest: RegisterOutput,
api: ApiClient,
store: LiveInputStreamStore<string>,
startTimestamp: number | undefined
startTimestamp: number | undefined,
logger: Logger
) {
this.api = api;
this.logger = logger;
this.outputId = outputId;
this.outputShutdownStateStore = new OutputShutdownStateStore();
this.shouldUpdateWhenReady = false;
Expand All @@ -52,7 +56,7 @@ class Output {
const onUpdate = () => this.throttledUpdate();
this.audioContext = new _liveCompositorInternals.AudioContext(onUpdate);
this.timeContext = new _liveCompositorInternals.LiveTimeContext();
this.internalInputStreamStore = new _liveCompositorInternals.LiveInputStreamStore();
this.internalInputStreamStore = new _liveCompositorInternals.LiveInputStreamStore(this.logger);
if (startTimestamp !== undefined) {
this.timeContext.initClock(startTimestamp);
}
Expand All @@ -68,6 +72,7 @@ class Output {
rootElement,
onUpdate,
idPrefix: `${outputId}-`,
logger: logger.child({ element: 'react-renderer' }),
});
}

Expand All @@ -90,9 +95,15 @@ class Output {
}

public async ready() {
this.throttledUpdate = throttle(async () => {
await this.api.updateScene(this.outputId, this.scene());
}, 30);
this.throttledUpdate = throttle(
async () => {
await this.api.updateScene(this.outputId, this.scene());
},
{
timeoutMs: 30,
logger: this.logger,
}
);
if (this.shouldUpdateWhenReady) {
this.throttledUpdate();
}
Expand All @@ -113,6 +124,7 @@ class OutputContext implements CompositorOutputContext {
public readonly audioContext: _liveCompositorInternals.AudioContext;
public readonly timeContext: _liveCompositorInternals.TimeContext;
public readonly outputId: string;
public readonly logger: Logger;
private output: Output;

constructor(
Expand All @@ -126,6 +138,7 @@ class OutputContext implements CompositorOutputContext {
this.audioContext = output.audioContext;
this.timeContext = output.timeContext;
this.outputId = outputId;
this.logger = output.logger;
}

public async registerMp4Input(
Expand Down Expand Up @@ -158,6 +171,7 @@ class OutputContext implements CompositorOutputContext {
};
});
}

public async unregisterMp4Input(inputId: number): Promise<void> {
await this.output.api.unregisterInput(
{
Expand Down
11 changes: 11 additions & 0 deletions ts/@live-compositor/core/src/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { _liveCompositorInternals } from 'live-compositor';

export type Logger = _liveCompositorInternals.Logger;

export enum LoggerLevel {
ERROR = 'error',
WARN = 'warn',
INFO = 'info',
DEBUG = 'debug',
TRACE = 'trace',
}
Loading

0 comments on commit 8da2701

Please sign in to comment.