hecate_om_content (hecate_om v0.20.0)

View Source

Put/get content on the mesh via macula's supervised macula_feeder/macula_download, blocking with a timeout — what an HTTP handler actually wants (bytes or an MCID back), instead of a pid it has nothing to do with.

Piece E, PLAN_HECATE_OM_MESH_WRAPPERS.md. Derived from hecate-tube's tube_content_put.erl/tube_content_get.erl, which carry a hard-won, confirmed-live lesson this module exists specifically to not lose: macula_download's direct-dial path (start_link_direct/4,5) only resolves content that has a content_announcement DHT record, and only *chunked* content gets one (macula_download's own moduledoc: "Only chunked content is discoverable this way"). A small blob — a logo, a thumbnail — never gets one, so direct-dial 404s even immediately after upload; confirmed live on beam02. This module always uses the *pooled* start_link/4,5 for both put and get, never start_link_direct, so put and get sides can never disagree about which path a given piece of content is reachable through.

This is the public facade, named for the operation a caller wants (put/get). The actual macula_feeder/macula_download behaviour callbacks live in the tiny hecate_om_content_feeder/ hecate_om_content_downloader modules — named for the SDK contract each satisfies rather than the operation, since neither carries any domain content of its own (that all lives here); see hecate_om_content_feeder's moduledoc for why they're separate files at all (both behaviours declare init/1, and the compiler rejects declaring both on one module).

{error, mesh_unavailable} when this service isn't attached to a pool or has no realm configured yet — same contract as hecate_om:mesh_handles/0, hecate_om_pubsub, and hecate_om_capabilities.

Summary

Functions

Get the bytes for Mcid using this service's own mesh handle and realm. Blocks until the get resolves or Opts's timeout (default 15000ms) elapses.

As get/1, with the same Opts as put/2.

Put Bytes into content storage using this service's own mesh handle and realm. Blocks until the put resolves or Opts's timeout (default 15000ms) elapses.

As put/1, with Opts: realm — put on a realm other than this service's own (same dual-realm need as pieces B/C — a fleet realm for hecate_om's own plumbing, a separate business/public realm for the content itself). timeout — milliseconds to wait for the outcome before cancelling the transfer and returning {error, timeout}. Default 15000.

The realm a put/get actually uses: Opts's realm override when given, otherwise this service's own default realm.

As start_feeder/2, for the get/download side — a caller-supplied -behaviour(macula_download)Module, same escape hatch, same reasoning as start_feeder/2.

As start_downloader/2, with Args passed to Module:init/1.

Start a supervised macula_feeder with a caller-supplied callback Module, using this service's own mesh handle and realm — the escape hatch for outcome handling put/1,2's block-and-return shape doesn't cover (e.g. a batch upload that wants a per-item completion side effect — updating a local progress counter — without blocking the caller on each one). Resolves hecate_om:mesh_handles/0 the same way put/1,2 does, so reaching for this instead doesn't mean duplicating that boilerplate. Module must implement -behaviour(macula_feeder) itself.

As start_feeder/2, with Args passed to Module:init/1.

As start_feeder/3, with Opts (realm only — see above).

Types

content_opts/0

-type content_opts() :: #{realm => binary(), timeout => pos_integer()}.

Functions

get(Mcid)

-spec get(macula:mcid()) -> {ok, binary()} | {error, term()}.

Get the bytes for Mcid using this service's own mesh handle and realm. Blocks until the get resolves or Opts's timeout (default 15000ms) elapses.

get(Mcid, Opts)

-spec get(macula:mcid(), content_opts()) -> {ok, binary()} | {error, term()}.

As get/1, with the same Opts as put/2.

put(Bytes)

-spec put(binary()) -> {ok, macula:mcid()} | {error, term()}.

Put Bytes into content storage using this service's own mesh handle and realm. Blocks until the put resolves or Opts's timeout (default 15000ms) elapses.

put(Bytes, Opts)

-spec put(binary(), content_opts()) -> {ok, macula:mcid()} | {error, term()}.

As put/1, with Opts: realm — put on a realm other than this service's own (same dual-realm need as pieces B/C — a fleet realm for hecate_om's own plumbing, a separate business/public realm for the content itself). timeout — milliseconds to wait for the outcome before cancelling the transfer and returning {error, timeout}. Default 15000.

resolve_realm(Opts, DefaultRealm)

-spec resolve_realm(content_opts(), binary()) -> binary().

The realm a put/get actually uses: Opts's realm override when given, otherwise this service's own default realm.

start_downloader(Module, Mcid)

-spec start_downloader(module(), macula:mcid()) -> {ok, pid()} | {error, term()}.

As start_feeder/2, for the get/download side — a caller-supplied -behaviour(macula_download)Module, same escape hatch, same reasoning as start_feeder/2.

start_downloader(Module, Mcid, Args)

-spec start_downloader(module(), macula:mcid(), term()) -> {ok, pid()} | {error, term()}.

As start_downloader/2, with Args passed to Module:init/1.

start_downloader(Module, Mcid, Args, Opts)

-spec start_downloader(module(), macula:mcid(), term(), #{realm => binary()}) ->
                          {ok, pid()} | {error, term()}.

As start_downloader/3, with Opts (realm only).

start_feeder(Module, Bytes)

-spec start_feeder(module(), binary()) -> {ok, pid()} | {error, term()}.

Start a supervised macula_feeder with a caller-supplied callback Module, using this service's own mesh handle and realm — the escape hatch for outcome handling put/1,2's block-and-return shape doesn't cover (e.g. a batch upload that wants a per-item completion side effect — updating a local progress counter — without blocking the caller on each one). Resolves hecate_om:mesh_handles/0 the same way put/1,2 does, so reaching for this instead doesn't mean duplicating that boilerplate. Module must implement -behaviour(macula_feeder) itself.

Args is passed to Module:init/1, same as macula_feeder:start_link/5 itself; default undefined when omitted. Opts accepts realm only (see put/2).

start_feeder(Module, Bytes, Args)

-spec start_feeder(module(), binary(), term()) -> {ok, pid()} | {error, term()}.

As start_feeder/2, with Args passed to Module:init/1.

start_feeder(Module, Bytes, Args, Opts)

-spec start_feeder(module(), binary(), term(), #{realm => binary()}) -> {ok, pid()} | {error, term()}.

As start_feeder/3, with Opts (realm only — see above).