Skip to content

Conversation

faultyserver
Copy link
Contributor

@faultyserver faultyserver commented Sep 29, 2022

Related Issue (if applicable):

#292

Description:

This PR implements a callBatch function that allows consumers to use the RequestBatch functionality from obs-websocket. RequestBatch was already part of the generated types (and in the protocol), so this doesn't change anything other than adding the function and the related types.

Because of the granularity of obs-websocket-v5's protocol design, getting the entire state of an input often requires multiple requests, and then multiple of those groups of requests for each input that you want to know about (example, just getting some audio-related state for all relevant inputs). In the context of any meaningfully-sized OBS setup, that could mean hundreds of requests in succession every time you want to refetch the state of OBS. Especially when the OBS host and the websocket client are not on the same computer (or are potentially even on different local networks), the latency of sending individual requests also adds up quickly.

Request batches are a really useful feature to avoid all of these issues and instead group requests into much more manageable and relevant bundles. Batches can contain large numbers of requests that obs-websocket will run when possible and then return all of the results together, saving on back and forth round trip times and encoding overhead.

I needed this feature for an event I was running a few months ago under exactly those circumstances and ended up implementing it myself using a vendored copy of obs-websocket-js, so this PR is largely just bringing those changes back here so that I can ditch the vendored copy and come back to using an official release.

Limitations

I tried for a while to get some smart typing for callBatch, like knowing what specific OBSRequestTypes would be in each slot of the returned array of results. It feels like there's some way to use mapped tuple types, but I couldn't figure it out with the way the OBSRequestTypes and OBSResponseTypes are currently structured as a single interface.

So, instead, consumers will currently need to cast each result to the type they are expecting, like:

const [res1] = obs.callBatch([{requestType: 'GetVersion'}]);
(res1.responseData as OBSResponseTypes['GetVersion']).obsVersion //=> 28.0.0

Comment on lines +313 to +320
export type RequestBatchRequest<T = keyof OBSRequestTypes> = T extends keyof OBSRequestTypes ? OBSRequestTypes[T] extends never ? {
requestType: T;
requestId?: string;
} : {
requestType: T;
requestId?: string;
requestData: OBSRequestTypes[T];
} : never;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This feels really dirty, but without it, requests that have never as the requestData value still want a requestData parameter, which is an impossible constraint to satisfy. So this is the compromise.

faultyserver added a commit to spyrothon/graphics that referenced this pull request Sep 29, 2022
I published
[`@faulty/obs-websocket-js`](https://www.npmjs.com/package/@faulty/obs-websocket-js)
with the changes made to implement request batches, and also [opened a
PR](obs-websocket-community-projects/obs-websocket-js#306)
to get the feature merged into an official release.

But with the first step done, we no longer need a vendored copy of the
library and can skip a lot of the build time it was taking up as well.
@t2t2 t2t2 linked an issue Sep 30, 2022 that may be closed by this pull request
Copy link
Collaborator

@t2t2 t2t2 left a comment

Choose a reason for hiding this comment

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

Also update readme.md, especially include the typing caveat

@faultyserver faultyserver requested a review from t2t2 September 30, 2022 14:44
@t2t2 t2t2 merged commit d25337b into obs-websocket-community-projects:master Sep 30, 2022
@faultyserver faultyserver deleted the add-request-batch branch September 30, 2022 20:57
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.

Request: Add ability to send RequestBatch commands
2 participants