Skip to content

Conversation

@ladvoc
Copy link
Contributor

@ladvoc ladvoc commented Oct 16, 2025

Summary by CodeRabbit

  • New Features

    • Added a UniFFI-based library exposing access token generation, verification, and unverified claim parsing.
    • Exposed build/version info and a log-forwarding API to stream Rust logs to host languages.
    • Added language bindings and runtime examples for Node.js, Python, and Swift.
  • Documentation

    • Added README and usage examples demonstrating binding usage and testing workflows.

✏️ Tip: You can customize this high-level summary in your review settings.

@ladvoc ladvoc force-pushed the ladvoc/uniffi-trial branch from 48449a0 to 41bd64c Compare October 31, 2025 23:59
pub struct Claims {
pub exp: u64,
pub iss: String,
pub nbf: u64,
Copy link

@pblazej pblazej Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] can we use SystemTime instead?

@ladvoc ladvoc force-pushed the ladvoc/uniffi-trial branch from a028a03 to 3faab50 Compare November 20, 2025 05:08
@pblazej
Copy link

pblazej commented Nov 20, 2025

The cargo make thing works great for me!

I'd also commit (local) Package.swift to packages/swift if you don't mind - does not pollute the others.

cc @1egoman

@pblazej pblazej mentioned this pull request Nov 20, 2025
1 task
@pblazej pblazej requested review from 1egoman and davidliu November 20, 2025 14:29
@pblazej pblazej requested a review from cloudwebrtc November 20, 2025 14:29
@pblazej
Copy link

pblazej commented Dec 11, 2025

I'll try to complete the Swift distribution path in the meantime.

@pblazej pblazej marked this pull request as ready for review December 12, 2025 09:52
@pblazej pblazej changed the title [WIP] UniFFI trial UniFFI trial Dec 12, 2025
@pblazej
Copy link

pblazej commented Dec 12, 2025

Here's more or less everything we need for local distribution, the tricky part is:

[tasks.swift-generate-manifest.env]
SPM_URL = { value = "https://dummy.com" }
SPM_CHECKSUM = { value = "1234" }

Let's assume the following workflow:

  • create tag rust-sdks/livekit-uniffi@*
  • create a release here with the artifacts

optionally:

Alternatively, we can skip Package.swift generation for release whatsoever and just track it in the above repo (it won't change that often). It will also bypass the cocoapods legacy problem here.

@pblazej
Copy link

pblazej commented Dec 12, 2025

I made a manual pre-release here: https://github.com/livekit/livekit-uniffi-xcframework
Swift SDK support: livekit/client-sdk-swift#822

@ladvoc if you're able to finish the release pipeline here, that would be cool (artifact is OK as mentioned above).

--platforms maccatalyst \
--platforms visionos \
--platforms tvos \
--lib-type dynamic \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And one more thing @ladvoc static release is still ~40MB whereas dylib ~1.8MB.

Dynamic one won't pass AppStore validation (we'd need to wrap it in a Framework).

90426: Invalid Swift Support. The SwiftSupport folder is missing. Rebuild your app using the current public (GM) version of Xcode and resubmit it.

I'd rather go for stripping the static one further, any ideas?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS in --release profile:

Ar Archive - 47 MB

Copy link

@pblazej pblazej Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, looks like DEAD_CODE_STRIPPING does the job and the bundle size increase is negligible (0.1 MB), moved back to static 729bc10

It also passes 🍏 validation 👍

I'm still open to optimization ideas 😄

script = """
# Rename modules inside the xcframework to match the module name (fix for Swift >6.2)
# Workaroud for cargo-swift v0.10.0 not supporting ffi_module_name
find "${SPM_NAME}/Rust${SPM_NAME}.xcframework" -depth -type d -name "Rust${SPM_NAME}" -exec bash -c 'mv "$1" "${1%Rust'${SPM_NAME}'}livekit_uniffiFFI"' _ {} \; || true
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to fix it here antoniusnaumann/cargo-swift#87

pblazej added a commit to livekit/client-sdk-swift that referenced this pull request Dec 18, 2025
Applies a patch to fix newer Swift versions 6.2+ failing when the module
name does not match folder name inside xcframework.

`cargo-swift` fix in progress,
livekit/rust-sdks#750 (comment)

tests
https://github.com/livekit/client-sdk-swift/actions/runs/20334177943/job/58416504807
@coderabbitai
Copy link

coderabbitai bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

Adds a new workspace member livekit-uniffi providing UniFFI-based FFI bindings (access token generation/verification, log forwarding, build metadata), associated build/tooling/templates/tests, and small updates to livekit-api (unverified claims helper) and workspace/license configs.

Changes

Cohort / File(s) Summary
Workspace & Licensing
Cargo.toml, licenserc.toml
Added livekit-uniffi to workspace members; updated license excludes (add livekit-uniffi/packages, allow Makefile.toml).
livekit-api token helper & tests
livekit-api/src/access_token.rs, livekit-api/src/test_token.txt
Added Claims::from_unverified(&str) to decode JWTs without signature validation; removed test-only expiry bypass; updated test token.
UniFFI crate manifest & gitignore
livekit-uniffi/Cargo.toml, livekit-uniffi/.gitignore
New crate manifest with cdylib/staticlib/lib, dependencies, build-deps, release profile; ignore rules for generated/ packages.
UniFFI library entry & bindgen
livekit-uniffi/src/lib.rs, livekit-uniffi/bindgen.rs
Library root exposing modules (access_token, log_forward, build_info) and uniffi scaffolding; added uniffi-bindgen binary entry.
Access token FFI module
livekit-uniffi/src/access_token.rs
New FFI-exposed types and functions: ApiCredentials, TokenOptions, Claims, token_generate, token_verify, token_claims_from_unverified, and related conversions/errors.
Log forwarding FFI module
livekit-uniffi/src/log_forward.rs
New log forwarding API: log_forward_bootstrap(LevelFilter), async log_forward_receive() -> Option<LogForwardEntry>, enums/record types, global logger using tokio mpsc and OnceCell.
Build metadata FFI
livekit-uniffi/src/build_info.rs
Added build_version() -> String returning crate version.
Bindings build & packaging orchestration
livekit-uniffi/Makefile.toml
Large cargo-make task set for cross-platform builds, bindgen generation, per-language packaging and packaging pipelines.
Language support templates & tooling
livekit-uniffi/support/*
Added Node and Swift support templates and scripts: download-lib.ts.tera, package.json.tera, tsup.config.ts, tsconfig.json, Swift Package templates.
Language test harnesses
livekit-uniffi/node_test/*, livekit-uniffi/python_test/main.py
Added Node test (index.ts, package.json, .gitignore) and Python test (main.py`) to exercise bindings: build_version, token generation/verification, and log forwarding consumption.

Sequence Diagrams

sequenceDiagram
    participant Client as Client (Node/Python/Swift)
    participant UniFFI as UniFFI Binding Layer
    participant Rust as livekit-uniffi (Rust)
    participant LiveKitAPI as livekit-api

    Client->>UniFFI: token_generate(options, credentials)
    UniFFI->>Rust: call token_generate
    Rust->>LiveKitAPI: construct & sign token
    LiveKitAPI-->>Rust: return JWT
    Rust-->>UniFFI: return JWT
    UniFFI-->>Client: return JWT
Loading
sequenceDiagram
    participant Client as Client (Node/Python/Swift)
    participant UniFFI as UniFFI Binding Layer
    participant RustLogger as Rust Logger (log_forward)
    participant Channel as MPSC Channel

    Client->>UniFFI: log_forward_bootstrap(level)
    UniFFI->>RustLogger: init global logger
    RustLogger->>Channel: create sender/receiver
    Note over RustLogger,Channel: Rust emits logs -> sent to Channel
    Client->>UniFFI: log_forward_receive()
    UniFFI->>Channel: poll receiver
    Channel-->>UniFFI: Option<LogForwardEntry>
    UniFFI-->>Client: deliver entry or None
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Poem

🐰 I hopped into bindings, small and spry,
Tokens I stitched, then sent them high,
From Rust burrow to Node and Swift,
Logs and claims in a tidy gift,
Cheers — a rabbit-built FFI tie!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'UniFFI trial' is vague and generic, using a non-descriptive term that fails to convey the main nature of the changeset beyond mentioning 'UniFFI'. Use a more specific title that describes the primary change, such as 'Add livekit-uniffi crate with UniFFI bindings and multi-platform support' or similar.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3472606 and f388f1d.

📒 Files selected for processing (1)
  • livekit-uniffi/Makefile.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • livekit-uniffi/Makefile.toml

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@livekit-uniffi/python_test/main.py`:
- Around line 44-52: The receive_log_messages loop using log_forward_receive can
block forever because the Rust channel may never close; update
receive_log_messages (or the caller) to avoid hanging by adding a timeout around
await log_forward_receive (e.g., with asyncio.wait_for) or by running the
receiver concurrently with the main token operations and cancelling it
afterwards; specifically modify the async function receive_log_messages and the
asyncio.run invocation so that log_forward_receive calls time out (handle
asyncio.TimeoutError and treat it as "no more logs") or run receive_log_messages
as a background task and cancel/join it after the token operations complete.

In `@livekit-uniffi/support/node/download-lib.ts.tera`:
- Around line 45-54: generateLibraryName currently switches on
'windows'/'macos'/'linux' but targetPlatform() returns Rust triple fragments
(e.g. 'pc-windows-msvc', 'apple-darwin', 'unknown-linux-gnu'), so no case
matches; update generateLibraryName to normalize or pattern-match the triples
returned by targetPlatform() (e.g. use startsWith/includes checks like
startsWith('pc-windows') or includes('darwin')/includes('linux') or map the
known triples to the three targets) and return the correct filename for each,
and add a default branch that throws/returns a clear error; reference
generateLibraryName and targetPlatform to locate and change the logic.
🧹 Nitpick comments (9)
livekit-uniffi/README.md (1)

19-21: Add language specifier to fenced code blocks.

The shell command blocks should specify a language for proper syntax highlighting and to satisfy markdown linting.

📝 Suggested fix
-```
+```bash
 cargo make swift-package

```diff
-```
+```bash
 cargo make node-package
</details>


Also applies to: 26-28

</blockquote></details>
<details>
<summary>livekit-uniffi/support/node/download-lib.ts.tera (1)</summary><blockquote>

`119-126`: **Consider adding type assertions for CLI arguments.**

The `parseArgs` values are typed as `string | boolean | undefined`, but `downloadLib` expects specific platform/arch types. Consider adding runtime validation or type assertions to catch invalid CLI inputs early.


<details>
<summary>♻️ Suggested improvement</summary>

```diff
+function assertValidPlatform(value: unknown): asserts value is TargetPlatform {
+  const valid = ['pc-windows-msvc', 'apple-darwin', 'unknown-linux-gnu'];
+  if (typeof value !== 'string' || !valid.includes(value)) {
+    throw new Error(`Invalid platform: ${value}`);
+  }
+}
+
+function assertValidArch(value: unknown): asserts value is TargetArch {
+  const valid = ['aarch64', 'x86_64'];
+  if (typeof value !== 'string' || !valid.includes(value)) {
+    throw new Error(`Invalid arch: ${value}`);
+  }
+}

 if (require.main === module) {
   // ...
   const { values } = parseArgs({ args: process.argv.slice(2), options });
+  if (values.platform) assertValidPlatform(values.platform);
+  if (values.arch) assertValidArch(values.arch);
   downloadLib(
     values.platform,
     // ...
livekit-uniffi/src/log_forward.rs (1)

102-102: Consider adding context to the unwrap() for future debugging.

While the unwrap() is currently safe (the receiver can't be dropped while the Logger exists in OnceCell), adding an expect() with a message would help if the design ever changes.

♻️ Suggested improvement
-        self.tx.send(record).unwrap();
+        self.tx.send(record).expect("Log receiver unexpectedly dropped");
livekit-uniffi/node_test/index.ts (1)

67-68: Handle async errors from main() to avoid silent failures.

Top-level promise rejections won’t be surfaced clearly; add a catch handler.

🛠️ Proposed fix
 if (require.main === module) {
-  main();
+  main().catch((err) => {
+    console.error(err);
+    process.exit(1);
+  });
 }
livekit-uniffi/node_test/package.json (1)

5-7: Consider cleaning up the placeholder test script.

The npm test script in this package is not currently invoked in CI or any automation (tests are run directly via npx tsx index.ts per the README). However, if someone manually runs npm test in this directory, it will unconditionally fail. Either replace it with "test": "tsx index.ts" or remove it entirely to avoid confusion.

livekit-uniffi/python_test/main.py (1)

21-21: Consider explicit imports instead of star import.

While star imports are acceptable for test files, using explicit imports would silence the static analysis warnings and make dependencies clearer:

from livekit_uniffi import (
    log_forward_bootstrap,
    log_forward_receive,
    LogForwardFilter,
    build_version,
    ApiCredentials,
    token_generate,
    token_verify,
    TokenOptions,
)
livekit-uniffi/Cargo.toml (1)

1-11: Consider reordering sections for conventional layout.

Placing [lib] before [package] is valid but unconventional. The typical Cargo.toml order is [package] first, followed by [lib], [[bin]], dependencies, and profiles. This is a minor style preference.

livekit-uniffi/support/node/package.json.tera (1)

12-17: Consider setting main to CJS for broader compatibility.

The main field points to the ESM entry (dist/index.mjs), but conventionally main should point to CommonJS for tools that don't support exports. Consider:

"main": "dist/index.js",
"module": "dist/index.mjs",

However, with engines.node >= 18 and proper exports field, this may not be necessary for your target audience.

livekit-uniffi/src/access_token.rs (1)

184-185: Address TODO: Remove test logging or the TODO comment.

The TODO indicates this debug log was added for testing log forwarding. Either remove the log statement if it's not needed in production, or remove the TODO comment if the logging should be kept.

Do you want me to help clean up these debug log statements across token_generate and token_verify?

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ec9971 and 3472606.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • livekit-uniffi/node_test/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (23)
  • Cargo.toml
  • licenserc.toml
  • livekit-api/src/access_token.rs
  • livekit-api/src/test_token.txt
  • livekit-uniffi/.gitignore
  • livekit-uniffi/Cargo.toml
  • livekit-uniffi/Makefile.toml
  • livekit-uniffi/README.md
  • livekit-uniffi/bindgen.rs
  • livekit-uniffi/node_test/.gitignore
  • livekit-uniffi/node_test/index.ts
  • livekit-uniffi/node_test/package.json
  • livekit-uniffi/python_test/main.py
  • livekit-uniffi/src/access_token.rs
  • livekit-uniffi/src/build_info.rs
  • livekit-uniffi/src/lib.rs
  • livekit-uniffi/src/log_forward.rs
  • livekit-uniffi/support/node/download-lib.ts.tera
  • livekit-uniffi/support/node/package.json.tera
  • livekit-uniffi/support/node/tsconfig.json
  • livekit-uniffi/support/node/tsup.config.ts
  • livekit-uniffi/support/swift/Package.swift.tera
  • livekit-uniffi/support/swift/[email protected]
🧰 Additional context used
🧬 Code graph analysis (1)
livekit-uniffi/python_test/main.py (3)
livekit-uniffi/src/log_forward.rs (2)
  • log_forward_bootstrap (28-32)
  • log_forward_receive (41-44)
livekit-uniffi/src/build_info.rs (1)
  • build_version (17-19)
livekit-uniffi/src/access_token.rs (2)
  • token_generate (180-230)
  • token_verify (238-250)
🪛 Gitleaks (8.30.0)
livekit-api/src/test_token.txt

[high] 1-1: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

🪛 markdownlint-cli2 (0.18.1)
livekit-uniffi/README.md

19-19: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


26-26: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🪛 Ruff (0.14.13)
livekit-uniffi/python_test/main.py

21-21: from livekit_uniffi import * used; unable to detect undefined names

(F403)


25-25: log_forward_bootstrap may be undefined, or defined from star imports

(F405)


25-25: LogForwardFilter may be undefined, or defined from star imports

(F405)


28-28: build_version may be undefined, or defined from star imports

(F405)


30-30: ApiCredentials may be undefined, or defined from star imports

(F405)


30-30: Possible hardcoded password assigned to argument: "secret"

(S106)


32-32: token_generate may be undefined, or defined from star imports

(F405)


33-33: TokenOptions may be undefined, or defined from star imports

(F405)


38-38: token_verify may be undefined, or defined from star imports

(F405)


46-46: log_forward_receive may be undefined, or defined from star imports

(F405)

🔇 Additional comments (25)
livekit-uniffi/node_test/.gitignore (1)

1-1: LGTM!

Standard .gitignore entry for Node.js projects.

livekit-uniffi/.gitignore (1)

1-2: LGTM!

Correctly excludes generated artifacts and packaged bindings from version control.

livekit-api/src/test_token.txt (1)

1-1: Test token is appropriate for unit testing.

The Gitleaks warning is a false positive—this is a test fixture with dummy credentials (myapikey as issuer, identity as subject) and a far-future expiration date (year 2100). The token is used for testing Claims::from_unverified and related token parsing functionality.

licenserc.toml (1)

16-16: LGTM!

The negation pattern correctly ensures Makefile.toml is checked for license headers despite the *.toml exclusion. Excluding livekit-uniffi/packages appropriately skips generated artifacts.

Also applies to: 21-21

livekit-uniffi/src/build_info.rs (1)

15-19: LGTM!

Clean implementation using compile-time env! macro to expose the crate version through UniFFI. The #[uniffi::export] attribute correctly generates cross-language bindings.

Cargo.toml (1)

8-8: LGTM!

The new livekit-uniffi crate is properly added to the workspace members.

livekit-uniffi/Makefile.toml (2)

24-26: Placeholder download URL needs to be updated before release.

The CDYLIB_DOWNLOAD_BASE_URL points to an example URL. Ensure this is updated to the actual release artifact location before merging or enabling release builds.


293-299: sed -i '' syntax is acceptable for this macOS-only manual task.

The swift-package task is a manual developer workflow documented in the README for local Swift package generation, not part of CI automation. Since XCFramework/Swift package building is inherently macOS-focused, the BSD sed syntax sed -i '' is appropriate and doesn't require portability fixes.

If this task were automated in CI on multiple platforms, portability would be a concern. As-is, no action needed.

livekit-uniffi/support/swift/[email protected] (1)

1-41: LGTM!

The Swift 6.0 manifest template properly handles development vs release profiles with appropriate binaryTarget configurations. The visionOS platform support (.v2) is correctly included.

livekit-uniffi/support/swift/Package.swift.tera (1)

8-13: visionOS is missing from platform list, unlike the Swift 6.0 template.

The [email protected] includes .visionOS(.v2) but this template omits it. Since visionOS support was added in Swift 5.9, this may be intentional (to support older Xcode versions) or an oversight.

livekit-uniffi/src/log_forward.rs (2)

41-44: try_lock() may silently return None under lock contention.

If multiple consumers call log_forward_receive() concurrently and one holds the lock, others will return None immediately (interpreted as "forwarding ended"). This could cause premature termination of log polling loops in client code.

Consider whether this is the intended behavior, or if you want to use .lock().await to wait for the mutex (though this changes semantics for single-consumer scenarios).


27-32: LGTM!

The bootstrap function correctly handles idempotent initialization while allowing subsequent level changes, as discussed in prior review comments.

livekit-uniffi/bindgen.rs (1)

15-19: LGTM for the bindgen entrypoint.

livekit-uniffi/support/node/tsconfig.json (1)

2-13: LGTM for the TypeScript compiler settings.

livekit-uniffi/support/node/tsup.config.ts (1)

3-15: LGTM for the tsup build configuration.

livekit-uniffi/src/lib.rs (1)

15-26: LGTM for the module wiring.

livekit-uniffi/node_test/index.ts (1)

57-63: The review comment is incorrect. The concern about empty strings terminating the loop does not apply here.

The function logForwardReceive() returns Option<LogForwardEntry> (TypeScript: LogForwardEntry | null), not a string. The check if (!message) correctly tests whether the entire object is null to detect loop termination. Empty content in the message field inside LogForwardEntry has no effect on the loop condition, so the current code handles the intended termination signal correctly.

livekit-api/src/access_token.rs (2)

154-167: LGTM!

The from_unverified implementation correctly disables signature validation while retaining exp and nbf time validation, which is appropriate for inspecting token contents without the secret. The method name clearly communicates the security implications.


398-441: LGTM!

Comprehensive test coverage for from_unverified:

  • Parses pre-existing token with room configuration
  • Parses freshly generated token
  • Correctly handles malformed token with altered signature

Good validation of the intended behavior.

livekit-uniffi/Cargo.toml (1)

28-34: LGTM!

The release profile is well-configured for FFI distribution:

  • panic = "abort" prevents undefined behavior from unwinding across FFI boundaries
  • Size optimizations (opt-level = "z", lto, strip) are appropriate for distributable binaries
livekit-uniffi/support/node/package.json.tera (1)

34-44: Potential trailing comma issue in generated JSON.

The template iterates over devDependencies and adds a trailing comma after each entry (line 37), which is followed by hardcoded entries. However, if devDependencies is empty, the first hardcoded entry ("tsup") won't have a preceding comma separator from the loop, and the JSON will still be valid.

The current pattern works but is fragile. If devDependencies has entries, the trailing comma from line 37 correctly precedes "tsup". Consider explicitly handling the comma separator for clarity:

💡 Alternative approach
"devDependencies": {
    {% for package_name, package_version in devDependencies %}
      "{{package_name | addslashes}}": "{{package_version | addslashes}}",
    {%- endfor %}
    "tsup": "^8.4.0",
    ...

The current approach works because of the trailing comma in the loop, but ensure the template is tested with both empty and populated devDependencies.

livekit-uniffi/src/access_token.rs (4)

21-29: LGTM!

Correct use of #[uniffi::remote(Error)] to expose the existing AccessTokenError from livekit_api. The flat_error attribute is appropriate for cross-language error handling.


107-139: LGTM!

Using u64 for timestamps (exp, nbf) is appropriate for FFI - it's more portable across target languages than SystemTime. The usize as u64 conversion at lines 126 and 128 is safe on both 32-bit (widening) and 64-bit (no-op) platforms.


237-250: LGTM!

The verification logic correctly handles optional credentials and converts the result to the UniFFI-compatible Claims type. Note: the TODO on line 242-243 should also be addressed (same as noted for token_generate).


252-262: LGTM!

Excellent documentation with a clear security warning. The implementation correctly delegates to the API layer's from_unverified and converts to the UniFFI-compatible type.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +44 to +52
async def receive_log_messages():
while True:
message = await log_forward_receive()
if message is None:
print("Log forwarding ended")
break
print(f"Log from Rust: {message}")

asyncio.run(receive_log_messages())
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Log receive loop may block indefinitely.

The async loop waits for log messages but has no mechanism to exit after the token operations complete. Unless the Rust log channel is explicitly closed, log_forward_receive() will block forever waiting for more messages, causing the test script to hang.

Consider adding a timeout or running the log receiver concurrently with the main operations:

💡 Suggested approach using asyncio.wait_for or concurrent execution
async def receive_log_messages():
    import asyncio
    try:
        while True:
            message = await asyncio.wait_for(log_forward_receive(), timeout=1.0)
            if message is None:
                print("Log forwarding ended")
                break
            print(f"Log from Rust: {message}")
    except asyncio.TimeoutError:
        print("No more log messages (timeout)")
🧰 Tools
🪛 Ruff (0.14.13)

46-46: log_forward_receive may be undefined, or defined from star imports

(F405)

🤖 Prompt for AI Agents
In `@livekit-uniffi/python_test/main.py` around lines 44 - 52, The
receive_log_messages loop using log_forward_receive can block forever because
the Rust channel may never close; update receive_log_messages (or the caller) to
avoid hanging by adding a timeout around await log_forward_receive (e.g., with
asyncio.wait_for) or by running the receiver concurrently with the main token
operations and cancelling it afterwards; specifically modify the async function
receive_log_messages and the asyncio.run invocation so that log_forward_receive
calls time out (handle asyncio.TimeoutError and treat it as "no more logs") or
run receive_log_messages as a background task and cancel/join it after the token
operations complete.

Comment on lines +45 to +54
function generateLibraryName(platform: TargetPlatform) {
switch (platform) {
case "windows":
return `${PACKAGE_NAME}.dll`;
case "macos":
return `lib${PACKAGE_NAME}.dylib`;
case "linux":
return `lib${PACKAGE_NAME}.so`;
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Platform string mismatch will cause generateLibraryName to never match.

The targetPlatform() function returns Rust target triple fragments ('pc-windows-msvc', 'apple-darwin', 'unknown-linux-gnu'), but generateLibraryName() switches on different strings ('windows', 'macos', 'linux'). This will cause all cases to fall through and return undefined.

🐛 Proposed fix
 function generateLibraryName(platform: TargetPlatform) {
   switch (platform) {
-    case "windows":
+    case "pc-windows-msvc":
       return `${PACKAGE_NAME}.dll`;
-    case "macos":
+    case "apple-darwin":
       return `lib${PACKAGE_NAME}.dylib`;
-    case "linux":
+    case "unknown-linux-gnu":
       return `lib${PACKAGE_NAME}.so`;
   }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function generateLibraryName(platform: TargetPlatform) {
switch (platform) {
case "windows":
return `${PACKAGE_NAME}.dll`;
case "macos":
return `lib${PACKAGE_NAME}.dylib`;
case "linux":
return `lib${PACKAGE_NAME}.so`;
}
}
function generateLibraryName(platform: TargetPlatform) {
switch (platform) {
case "pc-windows-msvc":
return `${PACKAGE_NAME}.dll`;
case "apple-darwin":
return `lib${PACKAGE_NAME}.dylib`;
case "unknown-linux-gnu":
return `lib${PACKAGE_NAME}.so`;
}
}
🤖 Prompt for AI Agents
In `@livekit-uniffi/support/node/download-lib.ts.tera` around lines 45 - 54,
generateLibraryName currently switches on 'windows'/'macos'/'linux' but
targetPlatform() returns Rust triple fragments (e.g. 'pc-windows-msvc',
'apple-darwin', 'unknown-linux-gnu'), so no case matches; update
generateLibraryName to normalize or pattern-match the triples returned by
targetPlatform() (e.g. use startsWith/includes checks like
startsWith('pc-windows') or includes('darwin')/includes('linux') or map the
known triples to the three targets) and return the correct filename for each,
and add a default branch that throws/returns a clear error; reference
generateLibraryName and targetPlatform to locate and change the logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants