Skip to content

add fallback stream support #606

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Conversation

vcashwin
Copy link
Contributor

@vcashwin vcashwin commented May 15, 2025

PR Type

Enhancement

Checklist before merge

  • Add env var to preprod envs
  • Add env var to prod env

Description

Add fallback stream support with round-robin selection
Implement server action for stream status fallback
Update prompt store to use dynamic stream key
Integrate React hooks and Zustand store


Changes walkthrough 📝

Relevant files
Enhancement
8 files
store.ts
Use dynamic fallback stream key for prompts                           
+9/-5     
actions.ts
Implement stream status action with HTTP fallback               
+127/-0 
route.ts
Delegate GET handler to status action                                       
+7/-110 
actions.ts
Add round-robin multiplayer fallback stream action             
+51/-0   
route.ts
Expose multiplayer stream info via API route                         
+8/-0     
VideoSection.tsx
Integrate multiplayer hooks for dynamic playback                 
+23/-7   
useMultiplayerStore.ts
Add Zustand store for multiplayer stream info                       
+33/-0   
useUpdateMultiplayerStream.ts
Create polling hook for multiplayer stream updates             
+28/-0   
Configuration changes
1 files
utils.ts
Define multiplayer fallback stream configurations               
+8/-0     

Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • Copy link

    vercel bot commented May 15, 2025

    The latest updates on your projects. Learn more about Vercel for Git ↗︎

    Name Status Preview Comments Updated (UTC)
    pipelines-app ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 16, 2025 8:13am

    Copy link

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Shared State

    Using a module‐level mutable variable activeStreamIndex for round‐robin in a serverless context can lead to inconsistent or lost state across invocations.

    let activeStreamIndex = 0;
    
    // Server action function to get multiplayer stream
    export async function getMultiplayerStream() {
      console.log("getMultiplayerStream:: START", activeStreamIndex);
      const stream = FALLBACK_STREAMS[activeStreamIndex];
    Missing Cleanup

    The setInterval inside useEffect has no cleanup via clearInterval, which can cause memory leaks and duplicate polls on remount.

        };
    
        setInterval(retrieveStatus, POLL_INTERVAL_IN_MS);
      }, []);
    };
    Error Handling

    The invocation of getMultiplayerStream and destructuring of its result isn’t guarded for failures or non‐200 statuses, risking runtime exceptions.

    const {
      data: { streamKey: targetStreamKey },
    } = await getMultiplayerStream();

    Copy link

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Security
    Use 401 for missing credentials

    Return a 401 Unauthorized status instead of 200 when authentication credentials are
    missing, and use the UNAUTHORIZED error message for clarity.

    apps/app/app/api/streams/[id]/status/actions.ts [64-68]

     if (!username || !password) {
       result.error =
    -    ERROR_MESSAGES.INTERNAL_ERROR + " - Missing auth credentials.";
    -  result.status = 200;
    +    ERROR_MESSAGES.UNAUTHORIZED + " - Missing auth credentials.";
    +  result.status = 401;
       return result;
     }
    Suggestion importance[1-10]: 8

    __

    Why: Returning a 401 status with the UNAUTHORIZED message correctly reflects authentication failures and adheres to standard HTTP semantics.

    Medium
    Possible issue
    Add error handling around stream fetch

    Wrap the call to getMultiplayerStream in a try/catch and validate that
    data.streamKey exists before destructuring to avoid runtime errors if the action
    fails or returns unexpected data. Return early on error.

    apps/app/app/api/prompts/store.ts [172-174]

    -const {
    -  data: { streamKey: targetStreamKey },
    -} = await getMultiplayerStream();
    +let targetStreamKey: string;
    +try {
    +  const result = await getMultiplayerStream();
    +  if (!result?.data?.streamKey) {
    +    console.error("getMultiplayerStream returned invalid data");
    +    return false;
    +  }
    +  targetStreamKey = result.data.streamKey;
    +} catch (e) {
    +  console.error("Error fetching multiplayer stream:", e);
    +  return false;
    +}
    Suggestion importance[1-10]: 7

    __

    Why: The destructuring of data.streamKey without checks can cause runtime errors, so adding try/catch and validation improves resilience.

    Medium
    General
    Add initial fetch and clear interval

    Invoke retrieveStatus immediately so you don’t wait for the first interval, and
    capture the interval ID so you can clear it in a cleanup function to avoid a memory
    leak.

    apps/app/hooks/useUpdateMultiplayerStream.ts [8-27]

     useEffect(() => {
    -  const retrieveStatus = async () => {
    -    console.log("useMultiplayerStream:: RETRIEVING STATUS");
    -    try {
    -      const response = await fetch("/api/streams/multiplayer");
    -      const data = await response.json();
    -      console.log("useMultiplayerStream:: FETCHED STATUS", data);
    -      setStreamInfo({
    -        streamKey: data.streamKey,
    -        originalPlaybackId: data.originalPlaybackId,
    -        transformedPlaybackId: data.transformedPlaybackId,
    -      });
    -    } catch (error) {
    -      console.error("useMultiplayerStream:: FETCHED FAILED");
    -      console.error("Error fetching multiplayer stream status:", error);
    -    }
    -  };
    -
    -  setInterval(retrieveStatus, POLL_INTERVAL_IN_MS);
    +  const retrieveStatus = async () => { /* ... */ };
    +  retrieveStatus();
    +  const intervalId = setInterval(retrieveStatus, POLL_INTERVAL_IN_MS);
    +  return () => clearInterval(intervalId);
     }, []);
    Suggestion importance[1-10]: 6

    __

    Why: Invoking the fetch immediately and cleaning up the interval prevents delayed initial data and potential memory leaks, improving component behavior.

    Low

    @vcashwin vcashwin temporarily deployed to Preview - e2e May 16, 2025 08:12 — with GitHub Actions Inactive
    @vcashwin vcashwin changed the title [wip] add fallback stream support add fallback stream support May 16, 2025
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    1 participant