Commit Graph

16163 Commits (dev)
 

Author SHA1 Message Date
Shlee 99462454d0
Merge pull request #7890 from pixelfed/staging
Staging
5 days ago
Shlee 5dd06228b9
Merge pull request #7889 from pixelfed/shleeable-patch-1
Update filesystems.php - set permissions type to handle "0666" as  octal integer
5 days ago
Shlee 459794ad5e
Update filesystems.php 5 days ago
Shlee 7b5e5ef00f
Merge pull request #7887 from pixelfed/staging
Staging
5 days ago
Shlee 62a6cf27e4
Merge pull request #7886 from pixelfed/test/media-perf-combined
Fix: Performance issues with Optipng on PNG uploads
6 days ago
Ashley 0bb59c880d Merge remote-tracking branches 'origin/fix/optipng-optimization-level' and 'origin/fix/media-wait-backoff' into test/media-perf-combined 6 days ago
Ashley 78e7dc0c92 Escalate the media-ready poll delay instead of a fixed 10s 6 days ago
Ashley 1298cd7201 Make optipng optimization level configurable, default to 2 6 days ago
Shlee b19607f131
Merge pull request #7884 from pixelfed/staging
Staging - 0.15.2
6 days ago
Shlee 9e6db372a9
Merge pull request #7883 from pixelfed/renovate/lock-file-maintenance
Lock file maintenance
6 days ago
renovate[bot] 32e9e786a7
Lock file maintenance 6 days ago
Shlee 200ae92fb4
Merge pull request #7882 from pixelfed/renovate/github-actions
Update github/codeql-action digest to 9b32540
6 days ago
Shlee dfbb3716bf
Update Pixelfed version to 0.15.2 6 days ago
Shlee 54617c5d03
Merge pull request #7881 from pixelfed/staging
Staging
6 days ago
renovate[bot] 5ee92d90fc
Update github/codeql-action digest to 9b32540 6 days ago
Shlee 64c87305fd
Merge pull request #7880 from pixelfed/serversideup-php-v5-reapply
ServerSideUp PHP v5 Upgrade
6 days ago
Shlee acdd8f2ae4
Update docker-compose.yml 6 days ago
Ashley 0877700507 Drop unused max-header-size caddyfile and its COPY 6 days ago
Ashley 15f8701698 Apply max_header_size to both HTTP and HTTPS listeners 6 days ago
Ashley 6fddf8f0f4 Follow CADDY_HTTP_PORT for the max_header_size listener 6 days ago
Ashley 82fa7c63b6 Target the 8080 listener for max_header_size to avoid duplicate servers block 6 days ago
Shlee 29cd115944
Update comments in .env.docker.example
Clarified comments regarding TRUSTED_PROXY and TRUST_PROXIES settings.
6 days ago
Ashley 9eab456c3b Revert "Merge pull request #7878 from pixelfed/revert/docker-serversideup-v5-hardening"
This reverts commit e17c93a8b9, reversing
changes made to 1b9c1780b1.
6 days ago
Shlee bc0c12412d
Merge pull request #7879 from pixelfed/staging
Staging
6 days ago
Shlee e17c93a8b9
Merge pull request #7878 from pixelfed/revert/docker-serversideup-v5-hardening
Revert "Merge pull request #7876 from pixelfed/docker/serversideup-v5…
6 days ago
Ashley a4268dfd3c Revert "Merge pull request #7876 from pixelfed/docker/serversideup-v5-hardening"
This reverts commit 1b9c1780b1, reversing
changes made to db24a53fce.
6 days ago
Shlee 383cab1774
Merge pull request #7877 from pixelfed/staging
Staging
6 days ago
Shlee 1b9c1780b1
Merge pull request #7876 from pixelfed/docker/serversideup-v5-hardening
Upgrade to serversideup v5, add Laravel health checks.
6 days ago
Shlee 63e3741fa6
Clean up PHP configuration in docker-compose.yml
Removed redundant PHP configuration comments and environment variables from multiple services.
6 days ago
Shlee dd2872ee39
Update max-header-size.caddyfile 6 days ago
Shlee d33016fafa
Update trusted proxy configuration in .env.docker.example
Reorganize trusted proxy settings and clarify comments.
6 days ago
Ashley ded1300894 Harden serversideup v5 Docker config and add Laravel health checks
- Register /up health route and point the web container healthcheck at it
- Add explicit healthcheck to the app service with a boot-aware start period
- Use healthcheck-horizon helper and round out the scheduler healthcheck
- Pin PHP_OPCACHE_VALIDATE_TIMESTAMPS=0 for baked-image code on all services
- Document TRUSTED_PROXY alongside TRUST_PROXIES, default to local
- Raise Caddy max_header_size to 64KiB via a baked global Caddyfile
6 days ago
Shlee 002615fe28
Merge pull request #7875 from pixelfed/staging
Staging
6 days ago
Shlee db24a53fce
Merge pull request #7873 from pixelfed/fix/timeline-stop-rewarm-empty
Stop re-warming an instance-wide timeline that has nothing to warm
6 days ago
Shlee 299f64dc3e
Merge pull request #7872 from pixelfed/fix/timeline-empty-page-cursor
Fix/timeline empty page cursor
6 days ago
Shlee 87c2d6bd9e
Merge pull request #7871 from pixelfed/fix/timeline-walk-empty-window
Walk on when a home window renders nothing
6 days ago
Shlee 7e1eea4977
Merge pull request #7870 from pixelfed/fix/timeline-prune-unrenderable
Prune home feed members that no longer render
6 days ago
Ashley 75a519e9a4 Stop re-warming an instance-wide timeline that has nothing to warm
A member count of zero was the only guard on the local and network warms,
and a warm that finds no eligible posts leaves the count at zero, so a new
instance, or one whose network feed has aged out, ran the full candidate
query on every single timeline request. Both warms now record an empty
outcome and both read paths consult that record as well as the count, so
the query runs once per hour instead of once per request. Any write to
either feed puts the warm straight back in play.

The lock closures return a value as well, so a request that lost the lock
is distinguishable from one that completed a warm; both used to come back
as null.
6 days ago
Ashley c37558a89c Derive the home next cursor from display order on an empty page
The feed is ranked by created_at, so the lowest id in a window is not the
member at the bottom of it: a remote post gets its id when we first store
it, not when it was published, so it can be the oldest id and the newest
post at once. The empty-page branch picked that numeric minimum, which
handed the client a cursor past everything between the remote post and
the real bottom of the window.

The cursor is now the display-order oldest member the request fetched. A
min_id client gets a prev cursor and no next, because it asked for newer
content and an older cursor points it at posts it already has. An empty
fetched window emits no Link at all, which is the end-of-feed signal;
previously the whole branch was unreachable because an empty window
returned early with no headers.
6 days ago
Ashley 266cbe9869 Walk on when a home window renders nothing
With boosts switched off, which is the default, a window of 51 members
that happens to be all boosts produced an empty page and stopped. One
followed account that mostly boosts is enough to do that indefinitely.
The same shape happens behind a muted account's run of posts or a block
of members that were just pruned.

The read now takes up to three further windows while the page is empty
and at least one member was dropped as unrenderable, as a boost, or by a
viewer filter. A page filtered out by the viewer's own rules does not
continue: they asked for that. Direction follows the request: a min_id
read deepens the same bounded window, because Redis enforces the floor
inside the query and walking older would hand a polling client posts it
already has, while any other read walks older from the last member it saw.

The Link cursor is derived from every member the request fetched rather
than the last pass alone, so it cannot point back into a block the client
has already walked.
6 days ago
Ashley 24e278759a Prune home feed members that no longer render
A member whose status has been deleted, or which cannot be resolved for
any other reason, was dropped from the page and left in the sorted set.
The feed then went on reporting hundreds of members while serving an
empty page, and nothing in the system ever removed them. The hydration
pass now removes such a member as it finds it and logs once per request
when it pruned anything.

Removing the last member makes Redis drop the set, so the feed becomes
genuinely absent and is rebuilt in the same request. That cannot loop:
the key is gone, so the branch is unreachable a second time.

Drops are also counted by reason now, because the reason decides what the
response is allowed to do. A page the viewer explicitly filtered out is
not a defect to recover from, so it still prunes nothing and runs no
query.
6 days ago
Shlee 3b56246c72
Merge pull request #7869 from pixelfed/fix/timeline-cold-boot-on-read
Rebuild a missing home feed from the read that found it missing
6 days ago
Ashley be59d31de9 Rebuild a missing home feed from the read that found it missing
The read path had three ways of answering a request whose window came
back empty, and all three could leave a user staring at a blank timeline.
It returned early whenever the set had any members, so a feed full of
unresolvable ids never got looked at. It only attempted a rebuild for a
request that sent no cursor, so a client holding a cursor got nothing on
every retry. And it marked the rebuild as done before knowing whether it
had worked, in a key nothing ever evicted, so a warm that threw
suppressed the next five minutes of attempts, and the throw itself
escaped the synchronous dispatch and turned the response into a 500.

A missing cached set is now rebuilt in-request behind a non-blocking
30-second lock: a reader that loses the lock serves nothing rather than
running a second full warm, one that wins releases it in a finally, and a
warm that throws is logged and leaves the feed eligible for the next
request. The page is then re-read through the same window helper, so the
cursor the client sent survives the rebuild. The rebuild goes 100 members
deep and queues the deepening job only when it filled that depth.

Three existing cases asserted the old bookkeeping rather than the
behaviour it was meant to protect. They keep their 200s and their empty
bodies and now assert the single-warm guarantee directly.
6 days ago
Shlee 8b4d2cc7d9
Merge pull request #7868 from pixelfed/fix/timeline-empty-feed-key
Record a genuinely empty feed under its own key
6 days ago
Ashley 78c0b65222 Record a genuinely empty feed under its own key
A feed with nothing in it and a feed that was never built look the same
from Redis: neither has a key. That is why the read path could not tell
"nothing to show" from "needs building", and why the only bookkeeping it
had was a 300-second marker written before the outcome was known and
evicted by nothing.

The trait now carries an empty-warm guard keyed on the resolved feed key,
holding the timestamp at which it lapses with a matching cache TTL. It is
written only by a warm that published nothing and resolved every
candidate it found: a candidate that would not resolve means the warm did
not finish, so the feed stays eligible and the failure is logged. A
forced warm never consults it.

Eviction is automatic for the instance-wide feeds through setAdd, and
explicit for home feeds, which have no key for a write to reach: the
author's own post, a followed local or remote account posting, a new
follow, and a followed hashtag getting a post all clear it. None of them
creates the feed key, so a follower who has never loaded a timeline still
does not get one.
6 days ago
Shlee 8d0e738f16
Merge pull request #7867 from pixelfed/fix/timeline-widen-warm
Widen the home warm before it concludes there is nothing to show
6 days ago
Ashley a5156b5f9e Widen the home warm before it concludes there is nothing to show
The warm scoped candidates to statuses newer than a six-month-old
snowflake and excluded boosts outright. Those are reasonable defaults
for the common case, but they were also the definition of "this feed is
empty": a viewer whose follows are dormant, or who follows only accounts
that boost, got no candidates and therefore no feed key, and because
every insert path is gated on that key existing, nothing could ever
repair it.

The candidate selection is now a parameterised pass. The first pass is
unchanged, including the per-account fairness that stops a prolific
account crowding out a capped feed. Only when it publishes nothing does
a second pass run, dropping the id floor, admitting shares, and
re-reading a following list that resolved to the viewer alone.
6 days ago
Shlee cb97ca5cbf
Merge pull request #7866 from pixelfed/fix/timeline-forced-warm-empty
Keep a populated home feed when a forced warm publishes nothing
6 days ago
Shlee bf74403100
Merge pull request #7865 from pixelfed/fix/timeline-maxid-below-feed
Serve the newest window when a max_id cursor falls below the feed
6 days ago
Ashley ef143a7880 Serve the newest window when a max_id cursor falls below the feed
Every cached timeline is trimmed, so a client that persisted a cursor
from before the last trim sends an id whose score sits under every
remaining member. The strict getter correctly finds nothing older, the
endpoint returned an empty page, and the client kept sending the same
dead cursor on every retry. A separate getRankedMaxIdOrRecent getter
leaves getRankedMaxId's strict contract intact: when the window is empty,
the feed still has members and the cursor resolves below the oldest of
them, the newest window is served instead. A cursor at or above the
oldest member is genuine end-of-feed and still answers with an empty page.

Re-derived on staging on top of the non-positive-cursor helpers
(normaliseHomeCursor/fetchHomeWindow), which it extends.

Verified standalone off staging:
HomeCursorRecoveryTest 6 passed; tests/Feature/Timeline + HomeFeed 77 passed.
6 days ago