fed-sx-m2: Step 7c — outbox delivery_set integration + 4 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 12m51s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 12m51s
outbox:publish/2 now computes the audience-resolved delivery set
after sign + log and stashes it in the Result proplist as
{delivery_set, [ActorId, ...]}. Step 8's delivery-queue worker
reads it off the publish result.
New compute_delivery_set/3(Request, Signed, Context):
- Pulls :follower_graph from Context (defaults to empty graph)
- Calls recipients_envelope/2 to synthesise a minimal envelope
from Request's :to / :cc + Signed's :actor
- Routes through delivery:delivery_set/3 unchanged
The envelope construct/4 surface doesn't carry :to / :cc (only
type / actor / published / object), and changing that ripples
through every envelope shape test. recipients_envelope/2 keeps
the compute boundary local to outbox.
4 new cases in outbox_publish.sh (17/17 total):
- Result :delivery_set empty default
- explicit :to -> [bob] in set
- followers symbol expands via Context :follower_graph
- self-suppression (alice in :to drops to []bob])
Module loads rebumped: follower_graph + delivery added as
dependencies; outbox shifts from epoch 5 to epoch 7. Internal
sx_server timeout bumped 240s -> 480s to fit the larger module
set.
Step 7 fully closed (7a delivery module + 7b public expansion
+ 7c outbox integration). Federation now has the end-to-end
audience resolution: an outbound activity's :to / :cc plus any
follower_graph expansion becomes a deduped recipient list ready
for Step 8 to dispatch.
Conformance running + adjacent gate running.
This commit is contained in:
@@ -92,12 +92,52 @@ publish(Request, Context) ->
|
||||
ok ->
|
||||
{ok, NewLog, _Seq} = log:append(LogState, Signed),
|
||||
broadcast(Signed, envelope_field(projections, Context)),
|
||||
Result = [{cid, cid_of(Signed)}, {activity, Signed}],
|
||||
DeliverySet = compute_delivery_set(Request, Signed, Context),
|
||||
Result = [{cid, cid_of(Signed)},
|
||||
{activity, Signed},
|
||||
{delivery_set, DeliverySet}],
|
||||
{ok, Result, NewLog};
|
||||
{error, Reason} ->
|
||||
{error, Reason, LogState}
|
||||
end.
|
||||
|
||||
%% compute_delivery_set/3 — Step 7c. Pulls the audience-resolved
|
||||
%% recipient list off the Request's `:to` / `:cc` fields (the
|
||||
%% envelope itself doesn't carry them — construct/4 only takes
|
||||
%% type / actor / published / object). Context's optional
|
||||
%% `:follower_graph` field carries a follower_graph state for
|
||||
%% `public` / `followers` audience expansion; absent -> empty graph,
|
||||
%% so explicit `:to` / `:cc` lists still resolve. Synthesises a
|
||||
%% recipient-shaped envelope from Request + Signed so the existing
|
||||
%% delivery:delivery_set/3 (which reads `:actor`, `:to`, `:cc`) can
|
||||
%% process it as-is.
|
||||
%%
|
||||
%% Step 8's delivery-queue worker reads `{delivery_set, [ActorId, ...]}`
|
||||
%% off the publish result and routes one HTTP POST per entry.
|
||||
|
||||
compute_delivery_set(Request, Signed, Context) ->
|
||||
Graph = case envelope_field(follower_graph, Context) of
|
||||
nil -> follower_graph:new();
|
||||
G -> G
|
||||
end,
|
||||
Recipients = recipients_envelope(Request, Signed),
|
||||
delivery:delivery_set(Recipients, [], Graph).
|
||||
|
||||
recipients_envelope(Request, Signed) ->
|
||||
Base = case envelope:get_field(actor, Signed) of
|
||||
{ok, A} -> [{actor, A}];
|
||||
_ -> []
|
||||
end,
|
||||
To = case envelope:get_field(to, Request) of
|
||||
{ok, T} -> [{to, T}];
|
||||
_ -> []
|
||||
end,
|
||||
Cc = case envelope:get_field(cc, Request) of
|
||||
{ok, C} -> [{cc, C}];
|
||||
_ -> []
|
||||
end,
|
||||
Base ++ To ++ Cc.
|
||||
|
||||
%% broadcast/2 — fire-and-forget cast to each named projection.
|
||||
%% Missing/nil/empty list is a no-op; the publish API does not
|
||||
%% require projections to exist. Activity is the post-sign Signed
|
||||
|
||||
Reference in New Issue
Block a user