mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-18 09:06:06 +00:00
Performance: Stream reorder in ChannelTableStreams now completes in a single PATCH request instead of three.
This commit is contained in:
parent
452a493df3
commit
bf60bbab54
3 changed files with 35 additions and 7 deletions
|
|
@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Optimized `ChannelTableStreams` (the expanded stream list inside each channel row) to reduce mount cost: moved pure helper functions and static values (`getCoreRowModel`, `defaultColumn`, stat categorization/formatting) outside the component so they're created once; stabilized the TanStack column definitions by removing `data` and `expandedAdvancedStats` from the `useMemo` dependency array (cell renderers receive the row at render time); switched advanced-stats toggle tracking from `useState` to a `useRef` + per-cell local state so toggling one stream's stats doesn't recreate the entire column array and table instance; memoized `dataIds`, `removeStream`, `handleDragEnd`, and `handleWatchStream` with `useMemo`/`useCallback`; extracted `StreamInfoCell` as a `React.memo` component with its own memoized stat categorization.
|
||||
- Fixed `getChannelStreams` store selector to return a stable empty-array reference instead of creating a new `[]` on every call for channels without streams, preventing unnecessary re-renders via the `shallow` comparator.
|
||||
- Memoized individual rows in `CustomTableBody` so that expanding/collapsing a channel only re-renders the 1-2 affected rows instead of all rows on the page. Callback functions (`renderBodyCell`, `expandedRowRenderer`) are stored in refs so memoized rows always use the latest version without the function references themselves defeating the memo comparator.
|
||||
- Stream reorder in `ChannelTableStreams` now completes in a single PATCH request instead of three. Previously dragging a stream to a new position triggered a PATCH, then `requeryStreams()` (re-fetching all streams), then `requeryChannels()` (re-fetching the entire paginated channel list with all embedded stream objects). The reorder now uses a dedicated `API.reorderChannelStreams()` path that issues only the PATCH, then updates the store in-place by reordering the existing stream objects without any network round-trips. On failure, `requeryChannels()` is called to restore correct state.
|
||||
- Fixed N+1 `UPDATE` queries in the stream-order write path. `ChannelSerializer.update()` and the bulk-edit view were calling `ChannelStream.save(update_fields=["order"])` once per stream whose position changed. Both now collect all modified `ChannelStream` objects and issue a single `ChannelStream.objects.bulk_update(…, ["order"])` call. Also removed an accidental `print(normalized_ids)` debug statement left in the serializer.
|
||||
- Eliminated repeated DB queries in the `ts_proxy` hot path. `StreamManager`, `StreamGenerator`, and `ProxyServer` were each calling `Channel.objects.get(uuid=...)` on every retry, reconnect, failover, and buffering event solely to retrieve `channel.name` for log events. `StreamManager` and `StreamGenerator` now fetch the channel name once at construction via a lightweight `values_list` query and store it as `self.channel_name`. `ProxyServer` caches the name in a `_channel_names` dict keyed by channel ID at channel-start time and pops it at channel-stop time. (Fixes #1138)
|
||||
|
||||
### Changed
|
||||
|
|
|
|||
|
|
@ -637,6 +637,35 @@ export default class API {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lightweight stream reorder: PATCHes only the stream order for a channel
|
||||
* without triggering requeryStreams or requeryChannels. The caller is
|
||||
* responsible for optimistic UI updates.
|
||||
*/
|
||||
static async reorderChannelStreams(channelId, streamIds) {
|
||||
try {
|
||||
await request(`${host}/api/channels/channels/${channelId}/`, {
|
||||
method: 'PATCH',
|
||||
body: { id: channelId, streams: streamIds },
|
||||
});
|
||||
// Update the channelsTable store in-place with the new stream order
|
||||
const store = useChannelsTableStore.getState();
|
||||
const channel = store.channels.find((c) => c.id === channelId);
|
||||
if (channel) {
|
||||
// Reorder the existing stream objects to match streamIds
|
||||
const streamMap = new Map(channel.streams.map((s) => [s.id, s]));
|
||||
const reorderedStreams = streamIds
|
||||
.map((id) => streamMap.get(id))
|
||||
.filter(Boolean);
|
||||
store.updateChannel({ ...channel, streams: reorderedStreams });
|
||||
}
|
||||
} catch (e) {
|
||||
errorNotification('Failed to reorder streams', e);
|
||||
// On failure, requery to restore correct state
|
||||
await API.requeryChannels();
|
||||
}
|
||||
}
|
||||
|
||||
static async updateChannels(ids, values) {
|
||||
const body = [];
|
||||
for (const id of ids) {
|
||||
|
|
|
|||
|
|
@ -643,13 +643,10 @@ const ChannelStreams = ({ channel }) => {
|
|||
const newIndex = currentIds.indexOf(over.id);
|
||||
const retval = arrayMove(prevData, oldIndex, newIndex);
|
||||
|
||||
const { streams: _, ...channelUpdate } = channel;
|
||||
API.updateChannel({
|
||||
...channelUpdate,
|
||||
streams: retval.map((row) => row.id),
|
||||
}).then(() => {
|
||||
API.requeryChannels();
|
||||
});
|
||||
API.reorderChannelStreams(
|
||||
channel.id,
|
||||
retval.map((row) => row.id)
|
||||
);
|
||||
|
||||
return retval;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue