A playlist's Data blob carries a member upstream ignores and misses one it writes #160
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A playlist's
Datablob is now written in upstream's declaration order (#150),but three of its members still disagree with what upstream serializes at the
pin.
Sharing::blobincrates/ephyra-core/src/rows/item.rswrites:LinkedChildrenshould not be there.Folder.LinkedChildrenis[JsonIgnore]at the pin — the links live in theLinkedChildrentable, whichephyra-db/src/linked.rsalready writes — so upstream's blob carries no suchmember.
PlaylistandBoxSetoverrideFilterLinkedChildrenPerUserand notthe property, so neither re-serializes it.
PlaylistMediaTypeis missing.Playlistdeclares it afterShares,unignored, so upstream's blob has it where this writes
LinkedChildren. Whata playlist holds is already modelled —
Write::playing— butSharingis nottold it.
OwnerUserIdis aGuid, not aGuid?. Upstream writes"00000000-0000-0000-0000-000000000000"for a playlist nobody owns; ourswrites
null.Sharing::parsealready reads the empty guid as nobody, so onlythe write side differs.
Why it is filed rather than fixed
No fixture holds a playlist row — the reference snapshots have none, so nothing
diffs one — and the second item is not a spelling change: something has to
decide what media type a playlist created through the route is written with, and
where
Sharinglearns it. That is a decision, not an edit.How to know it is done
A playlist created through
POST /Playlistson both servers leaves the sameBaseItems.Datatext onceDateLastSavedis masked, anda_playlists_blob_is_written_in_the_order_upstream_declares_itinrows/item.rssays what the members are as well as what order they are in.That takes a container of its own from the pinned image over a
cp -acopy ofa snapshot — creating a playlist is a write.
House rules
Tests run under
cargo nextest; upstream's source is the checkout inupstream/at the pin. The reference on:8096is read-only. Anythingneeding a write gets its own container from the pinned image over a
cp -acopyof a snapshot, on its own ports.
Two of the three are fixed; the middle one is what is left, and it is worse
than filed.
OwnerUserIdand the guid spelling — fixed (6684877). The severity wasnot what it looked like either way: upstream registers a
JsonGuidConverterwhose
Readmaps a null toGuid.Empty, so"OwnerUserId":nullwas readcorrectly and lost nothing. What it was is a difference in the diffed column.
The same converter's
Writeisvalue.ToString("N")— unhyphenated — soevery guid in this blob was spelled wrong as well,
Shares[].UserIdincluded.Both now go through
to_wire(), and an unowned playlist carries the empty guid.LinkedChildren/PlaylistMediaType— still open, and it costs a read.Playlist.MediaTypeispublic override MediaType MediaType => PlaylistMediaType— a getter with no setter. So a playlist this server wrote and upstream then
opens gets
PlaylistMediaType = MediaType.Unknown, the enum default, and theMediaTypecolumn cannot repair it:SupportsPlayedStatus, playback andclient-side filtering all see an untyped playlist. It is not only a text
difference.
The two members sit in the same slot —
PlaylistMediaTypeis declared betweenSharesand the inherited members, exactly whereLinkedChildrenis writtennow — so swapping them fixes the text and the read together. What still needs
deciding is where
Sharinglearns the media type:Write::playingalreadymodels it, and nothing hands it to the blob writer.
Fixed in
b315fd8.Sharing::blobtakes the media type — both call sitesalready had it in hand for
playing()— and writesPlaylistMediaTypein theslot
LinkedChildrenoccupied, spelled the wayJsonStringEnumConverterspells an enum.
a_playlists_blob_names_the_media_type_and_not_its_childrenincrates/ephyra-http/tests/playlists.rscreates a playlist through the routeand reads the stored blob back out of the database, so it fails on either half.
A review of the fix found the member is now load-bearing in a way the port was
not ready for, so
4fb618dfollows it.ephyra_core::item::MediaTypecarried three of upstream's five — noPhoto,no
Book— and every playlist path collapsed the rest to audio. Harmless whilethat only reached the
MediaTypecolumn, which upstream ignores for aplaylist; not harmless once the blob carries the member upstream reads.
written()re-derived the value on every edit (_ => Audio). Upstream'sUpdatePlaylistmutates the loaded playlist and never touchesPlaylistMediaType, so a playlist it resolved off a[playlist]directorywith no
playlist.xml—Unknown— became an audio one for good on thefirst rename. It reads the stored value now.
VideoandAudio, off the query and off what theplaylist holds. Upstream keeps any non-
Unknownrequest.MediaTypeandtakes
item.MediaTypestraight off the first item, falling back toAudioonly when nothing said anything — which
linked::holdingnow matches.an_edit_keeps_a_media_type_this_server_would_not_have_chosencovers the firstand fails on the old
written(); the blob test gained a films-only playlist,since asserting
Audioalone could not fail whileAudiois also thenothing-recognised fallback.