Skip to content

Module dev_router.erl

A device that routes outbound messages from the node to their appropriate network recipients via HTTP.

Description

All messages are initially routed to a single process per node, which then load-balances them between downstream workers that perform the actual requests.

The routes for the router are defined in the routes key of the Opts, as a precidence-ordered list of maps. The first map that matches the message will be used to determine the route.

Multiple nodes can be specified as viable for a single route, with the Choose key determining how many nodes to choose from the list (defaulting to 1). The Strategy key determines the load distribution strategy, which can be one of Random, By-Base, or Nearest. The route may also define additional parallel execution parameters, which are used by the hb_http module to manage control of requests.

The structure of the routes should be as follows:

       Node?: The node to route the message to.
       Nodes?: A list of nodes to route the message to.
       Strategy?: The load distribution strategy to use.
       Choose?: The number of nodes to choose from the list.
       Template?: A message template to match the message against, either as a
                  map or a path regex.

Function Index

add_route_test/0*
apply_route/3*Apply a node map's rules for transforming the path of the message.
apply_routes/3*Generate a uri key for each node in a route.
binary_to_bignum/1*Cast a human-readable or native-encoded ID to a big integer.
by_base_determinism_test/0*Ensure that By-Base always chooses the same node for the same hashpath.
choose/5*Implements the load distribution strategies if given a cluster.
choose_1_test/1*
choose_n_test/1*
device_call_from_singleton_test/0*
do_apply_route/3*
dynamic_route_provider_test/0*
dynamic_router/0*
dynamic_router_test_/0*Example of a Lua module being used as the route_provider for a HyperBEAM node.
dynamic_routing_by_performance/0*
dynamic_routing_by_performance_test_/0*Demonstrates routing tables being dynamically created and adjusted according to the real-time performance of nodes.
explicit_route_test/0*
extract_base/2*Extract the base message ID from a request message.
field_distance/2*Calculate the minimum distance between two numbers (either progressing backwards or forwards), assuming a 256-bit field.
find_target_path/2*Find the target path to route for a request message.
generate_hashpaths/1*
generate_nodes/1*
get_routes_test/0*
info/1Exported function for getting device info, controls which functions are exposed via the device API.
info/3HTTP info response providing information about this device.
load_routes/1*Load the current routes for the node.
local_dynamic_router/0*
local_dynamic_router_test_/0*Example of a Lua module being used as the route_provider for a HyperBEAM node.
local_process_route_provider/0*
local_process_route_provider_test_/0*
lowest_distance/1*Find the node with the lowest distance to the given hashpath.
lowest_distance/2*
match/3Find the first matching template in a list of known routes.
match_routes/3*
match_routes/4*
preprocess/3Preprocess a request to check if it should be relayed to a different node.
register/3Register function that allows telling the current node to register a new route with a remote router node.
request_hook_reroute_to_nearest_test/0*Test that the preprocess/3 function re-routes a request to remote peers via ~relay@1.0, according to the node's routing table.
route/2Find the appropriate route for the given message.
route/3
route_provider_test/0*
route_regex_matches_test/0*
route_template_message_matches_test/0*
routes/3Device function that returns all known routes.
simulate/4*
simulation_distribution/2*
simulation_occurences/2*
strategy_suite_test_/0*
template_matches/3*Check if a message matches a message template or path regex.
unique_nodes/1*
unique_test/1*
weighted_random_strategy_test/0*
within_norms/3*

Function Details

add_route_test/0 *

add_route_test() -> any()

apply_route/3 *

apply_route(Msg, Route, Opts) -> any()

Apply a node map's rules for transforming the path of the message. Supports the following keys: - opts: A map of options to pass to the request. - prefix: The prefix to add to the path. - suffix: The suffix to add to the path. - replace: A regex to replace in the path.

apply_routes/3 *

apply_routes(Msg, R, Opts) -> any()

Generate a uri key for each node in a route.

binary_to_bignum/1 *

binary_to_bignum(Bin) -> any()

Cast a human-readable or native-encoded ID to a big integer.

by_base_determinism_test/0 *

by_base_determinism_test() -> any()

Ensure that By-Base always chooses the same node for the same hashpath.

choose/5 *

choose(N, X2, Hashpath, Nodes, Opts) -> any()

Implements the load distribution strategies if given a cluster.

choose_1_test/1 *

choose_1_test(Strategy) -> any()

choose_n_test/1 *

choose_n_test(Strategy) -> any()

device_call_from_singleton_test/0 *

device_call_from_singleton_test() -> any()

do_apply_route/3 *

do_apply_route(X1, R, Opts) -> any()

dynamic_route_provider_test/0 *

dynamic_route_provider_test() -> any()

dynamic_router/0 *

dynamic_router() -> any()

dynamic_router_test_/0 *

dynamic_router_test_() -> any()

Example of a Lua module being used as the route_provider for a HyperBEAM node. The module utilized in this example dynamically adjusts the likelihood of routing to a given node, depending upon price and performance. also include preprocessing support for routing

dynamic_routing_by_performance/0 *

dynamic_routing_by_performance() -> any()

dynamic_routing_by_performance_test_/0 *

dynamic_routing_by_performance_test_() -> any()

Demonstrates routing tables being dynamically created and adjusted according to the real-time performance of nodes. This test utilizes the dynamic-router script to manage routes and recalculate weights based on the reported performance.

explicit_route_test/0 *

explicit_route_test() -> any()

extract_base/2 *

extract_base(RawPath, Opts) -> any()

Extract the base message ID from a request message. Produces a single binary ID that can be used for routing decisions.

field_distance/2 *

field_distance(A, B) -> any()

Calculate the minimum distance between two numbers (either progressing backwards or forwards), assuming a 256-bit field.

find_target_path/2 *

find_target_path(Msg, Opts) -> any()

Find the target path to route for a request message.

generate_hashpaths/1 *

generate_hashpaths(Runs) -> any()

generate_nodes/1 *

generate_nodes(N) -> any()

get_routes_test/0 *

get_routes_test() -> any()

info/1

info(X1) -> any()

Exported function for getting device info, controls which functions are exposed via the device API.

info/3

info(Msg1, Msg2, Opts) -> any()

HTTP info response providing information about this device

load_routes/1 *

load_routes(Opts) -> any()

Load the current routes for the node. Allows either explicit routes from the node message's routes key, or dynamic routes generated by resolving the route_provider message.

local_dynamic_router/0 *

local_dynamic_router() -> any()

local_dynamic_router_test_/0 *

local_dynamic_router_test_() -> any()

Example of a Lua module being used as the route_provider for a HyperBEAM node. The module utilized in this example dynamically adjusts the likelihood of routing to a given node, depending upon price and performance.

local_process_route_provider/0 *

local_process_route_provider() -> any()

local_process_route_provider_test_/0 *

local_process_route_provider_test_() -> any()

lowest_distance/1 *

lowest_distance(Nodes) -> any()

Find the node with the lowest distance to the given hashpath.

lowest_distance/2 *

lowest_distance(Nodes, X) -> any()

match/3

match(Base, Req, Opts) -> any()

Find the first matching template in a list of known routes. Allows the path to be specified by either the explicit path (for internal use by this module), or route-path for use by external devices and users.

match_routes/3 *

match_routes(ToMatch, Routes, Opts) -> any()

match_routes/4 *

match_routes(ToMatch, Routes, Keys, Opts) -> any()

preprocess/3

preprocess(Msg1, Msg2, Opts) -> any()

Preprocess a request to check if it should be relayed to a different node.

register/3

register(M1, M2, Opts) -> any()

Register function that allows telling the current node to register a new route with a remote router node. This function should also be idempotent. so that it can be called only once.

request_hook_reroute_to_nearest_test/0 *

request_hook_reroute_to_nearest_test() -> any()

Test that the preprocess/3 function re-routes a request to remote peers via ~relay@1.0, according to the node's routing table.

route/2

route(Msg, Opts) -> any()

Find the appropriate route for the given message. If we are able to resolve to a single host+path, we return that directly. Otherwise, we return the matching route (including a list of nodes under nodes) from the list of routes.

If we have a route that has multiple resolving nodes, check the load distribution strategy and choose a node. Supported strategies:

            All: Return all nodes (default).
         Random: Distribute load evenly across all nodes, non-deterministically.
        By-Base: According to the base message's hashpath.
      By-Weight: According to the node's <code>weight</code> key.
        Nearest: According to the distance of the node's wallet address to the
                 base message's hashpath.

By-Base will ensure that all traffic for the same hashpath is routed to the same node, minimizing work duplication, while Random ensures a more even distribution of the requests.

Can operate as a ~router@1.0 device, which will ignore the base message, routing based on the Opts and request message provided, or as a standalone function, taking only the request message and the Opts map.

route/3

route(X1, Msg, Opts) -> any()

route_provider_test/0 *

route_provider_test() -> any()

route_regex_matches_test/0 *

route_regex_matches_test() -> any()

route_template_message_matches_test/0 *

route_template_message_matches_test() -> any()

routes/3

routes(M1, M2, Opts) -> any()

Device function that returns all known routes.

simulate/4 *

simulate(Runs, ChooseN, Nodes, Strategy) -> any()

simulation_distribution/2 *

simulation_distribution(SimRes, Nodes) -> any()

simulation_occurences/2 *

simulation_occurences(SimRes, Nodes) -> any()

strategy_suite_test_/0 *

strategy_suite_test_() -> any()

template_matches/3 *

template_matches(ToMatch, Template, Opts) -> any()

Check if a message matches a message template or path regex.

unique_nodes/1 *

unique_nodes(Simulation) -> any()

unique_test/1 *

unique_test(Strategy) -> any()

weighted_random_strategy_test/0 *

weighted_random_strategy_test() -> any()

within_norms/3 *

within_norms(SimRes, Nodes, TestSize) -> any()