Module peer_worker

A managed PPSPP UDP-based Peer.

Behaviours: gen_server.

Description

The peer_worker provides a wrapper around the standard gen_udp server spawning an additional erlang process for every received datagram. At startup, the peer_worker registers itself in the gproc registry with the assigned UDP port.

Note that every port has a 1-to-1 association to a specific swarm, comprising options, IP, and port. The main reason for this is to be able to pass these swarm options through to the packet decoder when checking that the requested hash is available in this swarm or not, without requiring additional lookups.

Data Types

state()


state() = {ppspp_options:options(), inet:port_number(), port()}

Function Index

code_change/3Default gen_server API.
get_url/1Create a URL for this endpoint that another peer could connect to.
handle_call/3Default gen_server API.
handle_cast/2Default gen_server API.
handle_info/2Receives UDP datagrams from gen_udp server and spawns a subsidiary process to manage it.
init/1Initialises the peer_worker and associated UDP port.
pid_to_port/1Looks up the port for a given pid.
start_link/2Start the peer with given port number and ppspp options which includes the root hash and chunk addressing specification.
stop/1Stops the server, given a corresponding UDP port.
terminate/2Closes down the peer_worker.
where_is/1Looks up the pid for a given port Returns an error tuple if the port cannot be found in the registry.

Function Details

code_change/3


code_change(OldVsn :: term(), State :: [state()], Extra :: term()) ->{ok, [state()]}

Default gen_server API.

get_url/1


get_url(Port :: inet:port_number()) -> {ok, string()}

Create a URL for this endpoint that another peer could connect to. As there is no official spec for URLs yet, I made one up. See url.md. A simple example is ppspp://example.net:7777/c89800bf

handle_call/3


handle_call(Message :: any(),From :: {pid(), any()},State :: [state()]) ->{reply, ok, state()}

Default gen_server API.

handle_cast/2


handle_cast(Message :: stop | any(), State :: [state()]) ->{noreply, state()}

Default gen_server API.

handle_info/2


handle_info(Packet :: term(), State :: [state()]) ->{noreply, [state()]} |{stop, {error, term()}, term()}

Receives UDP datagrams from gen_udp server and spawns a subsidiary process to manage it. Returns noreply tuple.

init/1


init(X1 :: [inet:port_number() | ppspp_options:options()]) ->{ok, [state()]}

Initialises the peer_worker and associated UDP port. Registers the worker with provided swarm options and UDP port in gproc.

pid_to_port/1


pid_to_port(Pid :: pid()) ->{ok, inet:port_number()} | {error, term()}

Looks up the port for a given pid. Returns an error tuple if the port cannot be found in the registry.


start_link(Port :: inet:port_number(),Swarm_Options :: ppspp_options:options()) ->ignore | {error, term()} | {ok, pid()}

Start the peer with given port number and ppspp options which includes the root hash and chunk addressing specification. These are required during subsequent packet parsing, even if the peer itself supports multiple swarms.

stop/1


stop(Port :: inet:port_number()) -> ok | {error, any()}

Stops the server, given a corresponding UDP port. Returns an error tuple if the port is no longer active.

terminate/2


terminate(Reason :: term(), X2 :: [state()]) -> ok

Closes down the peer_worker. Returns reason and brief statistics.

where_is/1


where_is(Port :: inet:port_number()) ->{ok, pid()} | {error, term()}

Looks up the pid for a given port Returns an error tuple if the port cannot be found in the registry.