mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-18 00:55:50 +00:00
Performance:
- Adding streams to a channel (per-row "Add to Channel" button and bulk "Add selected to Channel") now completes in a single PATCH request instead of three. Previously each operation called `API.updateChannel` (which internally triggered `requeryStreams`), then `requeryChannels()`. Both paths now use a dedicated `API.addStreamsToChannel()` method that issues only the PATCH, merges the existing channel streams with the newly added stream objects locally, and updates the store in-place, no `requeryStreams` or `requeryChannels` round-trips. - Removed an unnecessary `requeryStreams()` call from `API.createChannelFromStream()`. Stream data does not change when a channel is created from it; the caller already calls `requeryChannels()` to display the new channel.
This commit is contained in:
parent
e1e60aa056
commit
e7cb13e8b0
3 changed files with 56 additions and 20 deletions
|
|
@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- `DraggableRow` (stream rows inside the expanded channel) is now wrapped in `React.memo` with a comparator on `row.original` identity and `index`, so rows whose stream data and position haven't changed are skipped entirely during re-renders caused by a sibling row moving.
|
||||
- Removed dead code in the `name` column cell: `playlists[stream.m3u_account]?.name` was indexing an array by an integer ID, which always returns `undefined`, the value was immediately overridden by `m3uAccountsMap`. The dead access and its fallback variable are gone; `m3uAccountsMap` is now the sole lookup.
|
||||
- Removed spurious `state: { data }` from the `useReactTable` call. `data` is a root-level TanStack Table option, not a controlled-state entry; passing it in `state` was a no-op but misleading.
|
||||
- Adding streams to a channel (per-row "Add to Channel" button and bulk "Add selected to Channel") now completes in a single PATCH request instead of three. Previously each operation called `API.updateChannel` (which internally triggered `requeryStreams`), then `requeryChannels()`. Both paths now use a dedicated `API.addStreamsToChannel()` method that issues only the PATCH, merges the existing channel streams with the newly added stream objects locally, and updates the store in-place, no `requeryStreams` or `requeryChannels` round-trips.
|
||||
- Removed an unnecessary `requeryStreams()` call from `API.createChannelFromStream()`. Stream data does not change when a channel is created from it; the caller already calls `requeryChannels()` to display the new channel.
|
||||
- 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
|
||||
|
|
|
|||
|
|
@ -638,7 +638,7 @@ export default class API {
|
|||
}
|
||||
|
||||
/**
|
||||
* Lightweight stream reorder: PATCHes only the stream order for a channel
|
||||
* PATCHes only the stream order for a channel
|
||||
* without triggering requeryStreams or requeryChannels. The caller is
|
||||
* responsible for optimistic UI updates.
|
||||
*/
|
||||
|
|
@ -666,6 +666,48 @@ export default class API {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PATCHes the channel with the
|
||||
* combined stream list and updates the channelsTable store in-place
|
||||
* using the stream objects the caller already has. Skips requeryStreams
|
||||
* (stream data doesn't change) and requeryChannels (we build the
|
||||
* result locally).
|
||||
*
|
||||
* @param {number} channelId
|
||||
* @param {Array} existingStreams - current channel.streams (full objects)
|
||||
* @param {Array} newStreams - stream objects to append
|
||||
*/
|
||||
static async addStreamsToChannel(channelId, existingStreams, newStreams) {
|
||||
try {
|
||||
const existing = existingStreams || [];
|
||||
// Deduplicate by ID, preserving order (existing first, new appended)
|
||||
const seen = new Set(existing.map((s) => s.id));
|
||||
const merged = [...existing];
|
||||
for (const s of newStreams) {
|
||||
if (!seen.has(s.id)) {
|
||||
seen.add(s.id);
|
||||
merged.push(s);
|
||||
}
|
||||
}
|
||||
|
||||
await request(`${host}/api/channels/channels/${channelId}/`, {
|
||||
method: 'PATCH',
|
||||
body: { id: channelId, streams: merged.map((s) => s.id) },
|
||||
});
|
||||
|
||||
// Update the channelsTable store in-place with the merged streams
|
||||
const store = useChannelsTableStore.getState();
|
||||
const channel = store.channels.find((c) => c.id === channelId);
|
||||
if (channel) {
|
||||
store.updateChannel({ ...channel, streams: merged });
|
||||
}
|
||||
} catch (e) {
|
||||
errorNotification('Failed to add streams to channel', e);
|
||||
// On failure, requery to restore correct state
|
||||
await API.requeryChannels();
|
||||
}
|
||||
}
|
||||
|
||||
static async updateChannels(ids, values) {
|
||||
const body = [];
|
||||
for (const id of ids) {
|
||||
|
|
@ -898,7 +940,6 @@ export default class API {
|
|||
useChannelsStore.getState().addChannel(response);
|
||||
}
|
||||
|
||||
await API.requeryStreams();
|
||||
return response;
|
||||
} catch (e) {
|
||||
errorNotification('Failed to create channel', e);
|
||||
|
|
|
|||
|
|
@ -89,15 +89,9 @@ const StreamRowActions = ({
|
|||
);
|
||||
|
||||
const addStreamToChannel = async () => {
|
||||
await API.updateChannel({
|
||||
id: targetChannelId,
|
||||
streams: [
|
||||
...new Set(
|
||||
channelSelectionStreams.map((s) => s.id).concat([row.original.id])
|
||||
),
|
||||
],
|
||||
});
|
||||
await API.requeryChannels();
|
||||
await API.addStreamsToChannel(targetChannelId, channelSelectionStreams, [
|
||||
row.original,
|
||||
]);
|
||||
};
|
||||
|
||||
const onEdit = useCallback(() => {
|
||||
|
|
@ -1040,15 +1034,14 @@ const StreamsTable = ({ onReady }) => {
|
|||
};
|
||||
|
||||
const addStreamsToChannel = async () => {
|
||||
await API.updateChannel({
|
||||
id: targetChannelId,
|
||||
streams: [
|
||||
...new Set(
|
||||
channelSelectionStreams.map((s) => s.id).concat(selectedStreamIds)
|
||||
),
|
||||
],
|
||||
});
|
||||
await API.requeryChannels();
|
||||
// Look up full stream objects from the current page data
|
||||
const selectedIdSet = new Set(selectedStreamIds);
|
||||
const newStreams = data.filter((s) => selectedIdSet.has(s.id));
|
||||
await API.addStreamsToChannel(
|
||||
targetChannelId,
|
||||
channelSelectionStreams,
|
||||
newStreams
|
||||
);
|
||||
};
|
||||
|
||||
const onRowSelectionChange = (updatedIds) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue