API

Express

This part contains basic convenience functions for creating and running Mango.jl simulations.

Mango.activateMethod
activate(runnable, container_list)

Actvate the container(s), which includes starting the containers and shutting them down after the runnable has been executed.

In most cases the runnable will execute code, which starts some process (e.g. some distributed negotiation) in the system to define the objective of the agent system.

Generally this function is a convenience function and is equivalent to starting all containers in the list, executing the code represented by runnable and shuting down the container again. Further, this function will handle errors occuring while running the runnable and ensure the containers are shutting down.

Examples

activate(your_containers) do 
   # Send the first message to start the system
   send_message(defined_agent, "Starting somethin", address(other_defined_agent))

   # wait some time
   wait(some_stopping_condition)
end
source
Mango.add_agent_composed_ofMethod
add_agent_composed_of(container, roles::Role...; suggested_aid::Union{Nothing,String}=nothing, base_agent::Union{Nothing,Agent}=nothing)

Create an agent which is composed of the given roles roles... and register the agent to the container.

If no base_agent is provided the agent struct used is an empty struct, which is only used as a container for the roles. The agent will be returned by the function.

Examples

agent = add_agent_composed_of(your_container, RoleA(), RoleB(), RoleC())
source
Mango.agent_composed_ofMethod
agent_composed_of(roles::Role...; base_agent::Union{Nothing,Agent}=nothing)

Create an agent which is composed of the given roles roles....

If no base_agent is provided the agent struct used is an empty struct, which is only used as a container for the roles. The agent will be returned by the function.

Examples

agent = agent_composed_of(RoleA(), RoleB(), RoleC())
source
Mango.create_mqtt_containerFunction
create_mqtt_container(host, port, client_id; codec=nothing)

Create a container using an MQTT protocol.

The host is expected to be the IP-adress of the broker, port is the port of the broker, the client_id is the id of the client which will be created and connected to the broker. Optionally you can also provide a codec as tuple of functions (first encode, second decode, see encode and decode).

Examples

agent = create_mqtt_container("127.0.0.1", 5555, "MyClient")
source
Mango.create_tcp_containerFunction
create_tcp_container(host, port; codec=nothing)

Create a container using an TCP protocol.

The host is expected to be the IP-adress to bind on, port is the port to bind on. Optionally you can also provide a codec as tuple of functions (first encode, second decode, see encode and decode).

Examples

agent = create_mqtt_container("127.0.0.1", 5555, "MyClient")
source
Mango.run_in_real_timeMethod
run_in_real_time(runnable::Function,
n_container::Int,
container_list_creator::Function,
agents::Agent...)

Let the agents run in containers (real time).

Distributes the given agents contained in the agenttuple to `ncontainer(real time container) and execute therunnable` (takes the container list as argument) while the container are active to run.

source
Mango.run_in_real_timeMethod
run_in_real_time(runnable::Function,
n_container::Int,
container_list_creator::Function,
agent_tuple::Tuple...)

Let the agents run in containers (real time).

Distributes the given agents contained in the agent_tuple to n_container (real time container) and execute the runnable (takes the container list as argument) while the container are active to run. It is possible to add supplementary information per agent as Tuple. For example (Agent, :aid => "my_aid"). The type of the containers are determined by the container_list_creator (ncontainer as argument, has to return a list of container with ncontainer entries).

source
Mango.run_in_simulationMethod
run_in_simulation(runnable::Function, agents::Agent, n_steps::Int; start_time::DateTime=DateTime(2000, 1, 1), step_size_s::Int=DISCRETE_EVENT)

Let the agents run as simulation in a simulation container.

Execute the runnable in SimulationContainer while the container is active to run. After the runnable the simulation container is stepped n_steps time with a step_size_s (default is discrete event). The start time can be specified using start_time.

source
Mango.run_with_mqttMethod
run_with_mqtt(runnable::Function,
n_container::Int,
agents::Agent...;
broker_host::String="127.0.0.1",
broker_port::Int=1883,
codec::Union{Nothing,Tuple{Function,Function}}=(encode, decode))

Let the agents run in mqtt containers (real time).

Distributes the given agents to n_container (real time container) and execute the runnable (takes the container list as argument) while the container are active to run. Here, MQTT container are created with the broker on broker_host and at the port broker_port. The containers are assignede client ids (client1 client2 ...)

source
Mango.run_with_mqttMethod
run_with_mqtt(runnable::Function,
n_container::Int,
agent_tuples::Tuple...;
broker_host::String="127.0.0.1",
broker_port::Int=1883,
codec::Union{Nothing,Tuple{Function,Function}}=(encode, decode))

Let the agents run in mqtt containers (real time).

Distributes the given agents to n_container (real time container) and execute the runnable (takes the container list as argument) while the container are active to run. It is possible to add supplementary information per agent as Tuple. For example (Agent, :aid => "my_aid", :topics => ["topic"]). Here, MQTT container are created with the broker on broker_host and at the port broker_port. The containers are assignede client ids (client1 client2 ...)

source
Mango.run_with_tcpMethod
run_with_tcp(runnable::Function,
n_container::Int,
agents::Agent...;
host::String="127.0.0.1",
start_port::Int=5555,
codec::Union{Nothing,Tuple{Function,Function}}=(encode, decode))

Let the agents run in tcp containers (real time).

Distributes the given agents to n_container (real time container) and execute the runnable (takes the container list as argument) while the container are active to run. Here, TCP container are created on host starting with the port start_port.

source
Mango.run_with_tcpMethod
run_with_tcp(runnable::Function,
n_container::Int,
agent_tuples::Union{Tuple,Agent}...;
host::String="127.0.0.1",
start_port::Int=5555,
codec::Union{Nothing,Tuple{Function,Function}}=(encode, decode))

Let the agents run in tcp containers (real time).

Distributes the given agent_tuples to n_container (real time container) and execute the runnable (takes the container list as argument) while the container are active to run. It is possible to add supplementary information per agent as Tuple. For example (Agent, :aid => "my_aid"). Here, TCP container are created on host starting with the port start_port.

source

Agent and Roles

Here, the API for the agent structs created with @agent/@role is listed.

Mango.forward_toMethod
forward_to(agent, content, forward_to_address, received_meta; kwargs...)

Forward the message to a specific agent using the metadata received on handling the message. This method essentially simply calls send_message on the input given, but also adds and fills the correct metadata fields to mark the message as forwarded.

For this the following meta data is set.

  • 'forwarded=true',
  • 'forwardedfromaddress=address of the original sender',
  • 'forwardedfromid=id of the original sender'
source
Mango.reply_toMethod
reply_to(
agent::AgentInterface,
content::Any,
received_meta::AbstractDict,

)

Convenience method to reply to a received message using the meta the agent received. This reduces the regular send_message as response send_message(agent, "Pong", AgentAddress(aid=meta["sender_id"], address=meta["sender_addr"])) to reply_to(agent, "Pong", meta)

Furthermore it guarantees that agent address (including the tracking id, which is part of the address!) is correctly passed to the mango container.

source
Mango.send_and_handle_answerMethod
send_and_handle_answer(
response_handler::Function,
agent::AgentInterface,
content::Any,
agent_address::Address;
calling_object::Any=nothing,
kwargs...)

Convenience method for sending tracked messages with response handler to the answer.

Sends a tracked message with a required response_handler to enable to use the syntax

send_and_handle_answer(...) do agent, message, meta
	# handle the answer
end
source
Mango.send_messageMethod
send_message(
agent::AgentInterface,
content::Any,
agent_address::Address;
kwargs...,

)

Send a message with the content content to the agent represented by agent_address.

This method will always set a sender_id. Additionally, further keyword arguments can be defined to fill the internal meta data of the message.

source
Mango.send_tracked_messageMethod
send_tracked_message(
agent::AgentInterface,
content::Any,
agent_address::Address;
response_handler::Function=(agent, message, meta) -> nothing,
calling_object::Any=nothing,
kwargs...,

)

Send a message with the content content to the agent represented by agent_address. This function will set a generated tracking_id to the address, which allows the identification of the dialog.

It is possible to define a response_handler, to which a function can be assigned, which handles the answer to this message call. Note that the resonding agent needs to use the same tracking id in the response, ideally reply_to is used to achieve this automatically.

This method will always set a sender_id. Additionally, further keyword arguments can be defines to fill the internal meta data of the message.

source
Mango.AgentType

Base-type for all agents in mango. Generally exists for type-safety and default implementations across all agents.

source
Mango.@agentMacro

Macro for defining an agent struct. Expects a struct definition as argument.

The macro does 3 things:

  1. It adds all baseline fields, defined in AGENT_BASELINE_FIELDS (the agent context context, the role handler role_handler, and the aid)
  2. It adds the supertype Agent to the given struct.
  3. It applies @with_def for default construction, the baseline fields are assigned to default values

Example

For example the usage could like this.

@agent struct MyAgent
	my_own_field::String
end

# results in

@with_def mutable struct MyAgent <: Agent
	# baseline fields...
	my_own_field::String
    my_own_field_with_default::String = "Default"
end

# so you would construct your agent like this

my_agent = MyAgent("own value", my_own_field_with_default="OtherValue")
source
Base.scheduleMethod
schedule(f::Function, agent::Agent, data::TaskData)

Delegates to the scheduler Scheduler

source
Mango.addMethod
add(agent::Agent, role::Role)

Add a role to the agent. This will add the role to the internal RoleHandler of the agent and it will bind the RoleContext to the role, which enables the role to interact with its environment.

source
Mango.add_forwarding_ruleMethod
add_forwarding_rule(agent, from_addr::AgentAddress, to_address::AgentAddress, forward_replies::Bool)

Add a rule for message forwarding.

After calling the agent will auto-forward every message coming from from_addr to to_address. If forwardreplies is set, all replies from `toaddressare forwarded back tofrom_addr`.

source
Mango.add_service!Method
add_service!(agent, service)

Add a service to the agent. Every service can exists exactly one time (stored by type).

source
Mango.delete_forwarding_ruleMethod
delete_forwarding_rule(agent, from_addr::AgentAddress, to_address::Union{Nothing,AgentAddress})

Delete an added forwarding rule. If to_address is not set, all rules are removed matching from_addr. If it set, both addresses need to match.

source
Mango.handle_messageMethod
handle_message(agent::Agent, message::Any, meta::Any)

Defines a function for an agent, which will be called when a message is dispatched to the agent. This methods will be called with any arriving message (according to the multiple dispatch of julia).

source
Mango.on_readyMethod
on_ready(agent::Agent)

Lifecycle Hook-in function called when the agent system as a whole is ready, the hook-in has to be manually activated using notify_ready(container::Container). If you use the activate function, it is called automatically.

source
Mango.on_startMethod
on_start(agent::Agent)

Lifecycle Hook-in function called when the container of the agent has been started, depending on the container type it may not be called (if there is no start at all, f.e. the simulation container)

source
Mango.service_of_typeMethod
service_of_type(agent, type::Type{T}, default=nothing)::Union{T,Nothing} where {T}

Return the current agent service of the type type.

If a default is set, this default service will be added to the agent as service of te type `type. The function is especially useful if you want to extend the functionality of the agent without having to change the internals of the agent, as this functions enables the user to add arbitrary data to the agent on which functions can be defined.

source
Mango.servicesMethod
services(agent)::Dict{DataType,Any}

Return a list of services, which were added to the agent.

source
Mango.shutdownMethod
shutdown(agent)

Will be called on shutdown of the container, in which the agent is living

source
Mango.AgentContextType

Context of the agent. Represents the environment for the specific agent. Therefore it includes a connection to the container, including all functions used for interacting with the environment for the agent.

source
Mango.@roleMacro

Macro for defining a role struct. Expects a struct definition as argument.

The macro does 3 things:

  1. It adds all baseline fields, defined in ROLE_BASELINE_FIELDS (the role context)
  2. It adds the supertype Role to the given struct.
  3. It applies @with_def for default construction, the baseline fields are assigned to default values

For example the usage could like this.

@role struct MyRole
	my_own_field::String
end

# results in

@with_def mutable struct MyRole <: Role
	# baseline fields...
	my_own_field::String
    my_own_field_with_default::String = "Default"
end

# so youl would construct your role like this

my_roel = MyRole("own value", my_own_field_with_default="OtherValue")
source
Mango.@sharedMacro

Mark the field as shared across roles.

This only works on structs with empty default constructor. Internally the marked field will be initialized with a model created by get_model. The model will be set when the Role is added to an agent.

Example

@kwdef struct Model
    field::Int = 0
end
@role struct MyRole
    @shared
    my_model::Model # per agent the exact same in every agent.
end
source
Mango.emit_eventMethod
emit_event(role::Role, event::Any; event_type::Any=nothing)

Emit an event to their subscriber.

source
Mango.get_modelMethod
get_model(role::Role, type::DataType)

Get a shared model from the pool. If the model does not exist yet, it will be created. Only types with default constructor are allowed!

Example

@kwdef struct ExampleModel
    my_field::Int = 0
end
role = ExampleRole()
model::ExampleModel = get_model(role, ExampleModel)
model.my_field = 1
model2::ExampleModel = get_model(role, ExampleModel)
# model == model2, it will also be the same for every role!
source
Mango.handle_eventMethod
handle_event(role::Role, src::Role, event::Any; event_type::Any)

Default function for arriving events, which get dispatched to the role.

source
Mango.handle_messageMethod

Default function for arriving messages, which get dispatched to the role. This function will be called for every message arriving at the agent of the role.

source
Mango.setupMethod
setup(role::Role)

Hook-in function to setup the role, after it has been added to its agent.

source
Mango.subscribe_eventFunction
subscribe_event(role::Role, event_type::Any, event_handler::Any, condition::Function)

Subscribe to specific types of events.

The types of events are determined by the condition function (accepting src and event) and by the event_type.

Example

struct MyEvent end
function custom_handler(role::Role, src::Role, event::Any, event_type::Any)
    # do your thing
end
subscribe_event(my_role, MyEvent, custom_handler, (src, event) -> aid(src) == "agent0")
source
Mango.subscribe_messageMethod
subscribe_message(role::Role, handler::Function, condition::Function)

Subscribe a message handler function (it need to have the signature (role, message, meta)) to the message dispatching. This handler function will be called everytime the given condition function ((message, meta) -> boolean) evaluates to true when a message arrives at the roles agent.

source
Mango.subscribe_sendMethod
subscribe_send(role::Role, handler::Function)

Subscribe a send_message hook in function (signature, (role, content, receiverid, receiveraddr; kwargs...)) to the message sending. The hook in function will be called every time a message is sent by the agent.

source
Mango.RoleType

Defines the type Role, which is the common base types for all roles in mango.

A Role is a bundled behavivor of an agent, which shall fulfill exactly one responsibility of an agent - the role. Technically speaking roles are the way to implement the composition pattern for agents, and to introduce modular archetypes, which shall be reused in different contexts.

source
Mango.RoleContextType

The RoleContext connects the role with its environment, which is mostly its agents. This is abstracted using the AgentInterface.

source

Real time container

This part contains the API related to the container construction, access and management.

Mango.AgentAddressType

Default AgentAddress base type, where the agent identifier is based on the container created agent id (aid). Used with the TCP protocol.

source
Mango.ContainerInterfaceType

Supertype of every container implementation. This acts as an interface to be used by the agents in their contexts.

source
Mango.MQTTAddressType

Connection information for an MQTT topic on a given broker. Used with the MQTT protocol.

source
Mango.agentsMethod
agents(container)

Return the agents of the container. The agents have a fixed order.

source
Mango.registerFunction
register(
container,
agent,
suggested_aid::Union{String,Nothing}=nothing;
kwargs...,

)

Register the agent to the container. Retun the agent itself for convenience.

Normally the aid is generated, however it is possible to suggest an aid, which will be used if it has not been used yet and if it is not conflicting with the default naming pattern (agent0, agent1, ...)

source
Mango.send_messageFunction
send_message(
container::ContainerInterface,
content::Any,
address::Address,
sender_id::Union{Nothing,String}=nothing;
kwargs...,

)

Send a message message using the given container container to the given address. Additionally, further keyword arguments can be defines to fill the internal meta data of the message.

source
Mango.shutdownMethod
shutdown(container)

Shutdown the container. Here all loops are closed, resources freed. It is recommended to use activate instead of shutting down manually.

source
Mango.startMethod
start(container)

Start the container. It is recommended to use activate instead of starting manually.

What exactly happend highly depends on the protocol and the container implmentation. For example, for TCP the container binds on IP and port, and the listening loop started.

source
Mango.ContainerType

The default container struct, representing the container as actor. The container is implemented by composition. This means the container consists of different implementations of base types, which define the behavior of the container itself. That being said, the same container generally able to send messages via different protocols using different codecs.

source
Mango.send_messageMethod
send_message(
container::Container,
content::Any,
mqtt_address::MQTTAddress,
kwargs...,

)

Send message version for MQTT topics. Note that there is no local message forwarding here because messages always get pushed to a broker and are not directly addressed to an agennt.

source
Mango.MQTTProtocolType

Protocol that abstracts a Mosquitto.jl client for Mango agents.

Creation

MQTTProtocol(client_id::String, broker_addr::InetAddr)

Create an MQTT client that connects to the broker at broker_addr with a client_id.

Fields

  • client - Mosquitto.jl client
  • broker_addr - address of the MQTT broker to connect to
  • connected - internal flag indicating connection status
  • active - internal flag indicating listen loop activity
  • msg_channel - message channel of the MQTT client
  • conn_channel - connection channel of the MQTT client
  • topictoaid - internal dictionary to track which registered agent is subscribed to which topic
source
Base.closeMethod
close(protocol::MQTTProtocol)

Disconnect the client from the broker and stop the message loop.

source
Mango.idMethod
id(protocol::MQTTProtocol)

Return the name the client is registered with at its broker.

source
Mango.initMethod
init(protocol::MQTTProtocol, stop_check::Function, data_handler::Function)

Initialize the Mosquitto looping task for the provided protocol and forward incoming messages to data_handler.

source
Mango.notify_registerMethod
notify_register(protocol::MQTTProtocol, aid::String; kwargs...)

Notify the protocol MQTT client that a new agent with aid has been registered.

Registration expects a kwarg topics to subscribe the agent to. If any topic is not yet subscribed by the client subscribe is called for it.

source
Mango.parse_idMethod
parse_id(_::MQTTProtocol, id::Any)::String

Return the id of the protocol as string (for compliance with container core).

source
Mango.sendMethod
send(protocol::MQTTProtocol, destination::String, message::Any)

Send a message to topic destination on the clients MQTT broker.

Returns

Return value and message id from MQTT library.

source
Mango.subscribeMethod
subscribe(protocol::MQTTProtocol, topic::String; qos::Int=1)

Subscribe the MQTT client of the protocol to topic with the given qos setting.

Returns

The Mosquitto error code and the message id.

source
Mango.ProtocolType

Type for all implementations of protocols, acts like an interface. A protocol defines the way message are processed and especially sent and received to an other peer. F.E. A protocol could be to send messages using a plain TCP connection, which would indicate that an internet address (host + port) is required for the communication.

The parameterized type T indicates type, which defines the address data of the receiver and sender.

Every protocol has to define two methods.

  1. send: defines the behavior of the protocol when an agents sends a messages
  2. init: defines the necessary steps to initialize (especially) the receiver loop and
	 therefore accepts a stop check and a data handler function to indicate when the receiver should stop, 
	 respectively how to dispatch the received message to the correct agent
source
Mango.idMethod
id(protocol::Protocol{T}) where {T}

Return the external identifier associated with the protocol (e.g. it could be the host+port, dns name, ...)

source
Mango.initMethod
init(protocol::Protocol{T}, stop_check::Function, data_handler::Function) where {T}

Initialized the protocols internal loops (if exists). In most implementation this would mean that the receiver loop is started. To handle received messages the data_handler function can be passed (msg, sender) -> your handling code.

To control the lifetime of the loops a stop_check should be passed (() -> boolean). If the stop check is true the loops will terminate. The exact behavior depends on the implementation though.

source
Mango.notify_registerMethod
notify_register(protocol::Protocol{T}, aid::String; kwargs...) where {T}

Protocol specific updates called when a new agent is registered.

source
Mango.parse_idMethod
parse_id(protocol::Protocol{T}, id_data::Any)::T where {T}

Parse different types to the correct type (if required). Should be implemented if the id type is not trivial.

source
Mango.sendMethod
send(protocol::Protocol{T}, destination::T, message::Any) where {T}

Send the message message to the agent known by the adress destination. How the message is exactly handled is determined by the protocol invoked.

The type of the destination has to match with the protocol. The function returns a boolean indicating whether the message was successfull sent

source
Mango.TCPProtocolType

Defines the tcp protocol. It holds a binding to an IP+Port and a tcp connection pool.

source
Base.closeMethod
close(pool::TCPConnectionPool)

Close the pool. This closes all connections. Further, this function will wait until all connection are released.

source
Base.closeMethod
close(protocol::TCPProtocol)

Release all tcp resources (binding on port and connections in the pool).

source
Mango.acquire_tcp_connectionMethod
acquire_tcp_connection(tcp_pool::TCPConnectionPool, key::InetAddr)::Union{TCPSocket,Nothing}

Acquire a tcp connection from the pool for the key (IP+Port). Return a TCPSocket if the pool is not closed yet, otherwise nothing will be returned

source
Mango.idMethod
id(protocol::TCPProtocol)

Return the technical address of the protocol (ip + port)

source
Mango.initMethod
init(protocol::TCPProtocol, stop_check::Function, data_handler::Function)

Initialized the tcp protocol. This starts the receiver and stop loop. The receiver loop will call the data_handler with every incoming message. Further it provides as sender adress a InetAddr object.

source
Mango.release_tcp_connectionMethod
release_tcp_connection(
tcp_pool::TCPConnectionPool,
key::InetAddr,
connection::TCPSocket,

)

Release the given tcp connection indexed by the key. This will put the connection back to the pool.

source
Mango.sendMethod
send(protocol::TCPProtocol, destination::InetAddr, message::Vector{UInt8})

Send a message message over plain TCP using destination as destination address. The message has to be provided as a form, which is writeable to an arbitrary IO-Stream.

Return true if successfull.

source

Simulation

In the following the APIs regarding the simulation container are listed.

Mango.create_simulation_containerMethod
create_simulation_container(start_time::DateTime; communication_sim::Union{Nothing,CommunicationSimulation}=nothing, task_sim::Union{Nothing,TaskSimulation}=nothing)

Create a simulation container. The container is intitialized with start_time.

Per default the SimpleCommunicationSimulation is used for communication simulation, and SimpleTaskSimulation for simulating the tasks of agents. To replace these, communication_sim and respectively task_sim can be set.

source
Mango.on_stepMethod
on_step(agent::Agent, world::World, clock::Clock, step_size_s::Real)

Hook-in, called on every step of the simulation container for every agent.

Further, the world is passed, which represents a common view on the environment in which agents can interact with eachother. Besides, the clock and the step_size_s can be used to read the current simulation time and the time which passes in the current step.

source
Mango.step_simulationFunction
step_simulation(container::SimulationContainer, step_size_s::Real=DISCRETE_EVENT)::Union{SimulationResult,Nothing}

Step the simulation using a continous time-span or until the next event happens.

For the continous simulation a step_size_s can be freely chosen, for the discrete event type DISCRETEEVENT has to be set for the `stepsize_s`.

source
Mango.SimpleCommunicationSimulationType

Default Implementation Communication Sim.

Implements a default delay which determines the delay of all messages if not specified in delay_s_directed_edge_dict. The dict can contain a mapping (aidsender, aidreceiver) -> delay, such that the delay is specified for every link between agents.

source
Mango.calculate_communicationMethod
calculate_communication(communication_sim::CommunicationSimulation, clock::Clock, messages::Vector{MessagePackage})::CommunicationSimulationResult

Calculate the communication using the specific communication simulation type. the current simulation time clock and the message which shall be sent in this step messages

source
Mango.SimulationSchedulerType

Specific scheduler, defined to be injected to the agents and intercept scheduling calls and especially the sleep calls while scheduling. This struct manages all necessary times and events, which shall fulfill the purpose to step the tasks only for a given step_size.

source
Mango.step_iterationMethod
step_iteration(task_sim::TaskSimulation, step_size_s::Real)::TaskIterationResult

Execute an iteration for a step of the simulation, which time is stepped with the step_size_s.

Can be called repeatedly if new tasks are spawn as a result of other tasks or as result of arriving messages.

source

Scheduling

In the following the APIs for scheduling TaskData is listed.

Mango.AwaitableTaskDataType

Schedule the function when the given awaitable is finished. Can be used with any type for which wait is defined.

source
Mango.ClockType

Default clock implementation, in which a static DateTime field is used.

source
Mango.ConditionalTaskDataType

Schedule the function when the condition is fulfilled. To check whether it is fulfilled the condition function is called every check_interval_s.

source
Mango.PeriodicTaskDataType

Task data describing a periodic task.

A periodic task is defined by an interval_s and optionally by a condition. The interval determines how long the delay is between the recurring action. The condition is a stopping condition (no argument) which shall return true if the task shall stop.

source
Mango.TaskDataType

TaskData type, which is the supertype for all data structs, which shall describe a specific task type. Together with a new method execute task for the inherting struct, new types of tasks can be introduced.

Example

struct InstantTaskData <: TaskData end
function execute_task(f::Function, scheduler::AbstractScheduler, data::InstantTaskData)
    f()
end
source
Base.scheduleMethod
schedule(f::Function, scheduler, data::TaskData)

Schedule a function (no arguments) using the specific scheduler (mostly the agent scheduler). The functino f is scheduled using the information in data, which specifies the way f will be scheduled.

source
Mango.sleep_untilMethod
sleep_until(condition::Function)

Sleep until the condition (no args -> bool) is met.

source
Mango.stop_taskMethod
stop_task(scheduler::AbstractScheduler, t::Task)

Stop the task t managed by scheduler. This only works if the task has been scheduled with the scheduler using a stoppable TaskData.

source

Topology

In the following the APIs for creating, aplying and using topologies is listed.

Graphs.SimpleGraphs.add_edge!Function
add_edge!(topology, node_id_from, node_id_to, directed=false)

Add an edge to the topology from node_id_from to node_id_to. If directed is true a directed edge is added, otherwise an undirected edge is added.

source
Mango.add!Method
add!(node, agent::Agent...)

Add an agents to the node.

source
Mango.add_node!Method
add_node!(topology, agents::Agent...)::Int

Add a node to the topology with a list (or a single) of agents attached.

source
Mango.assign_agentMethod
assign_agent(assign_condition::Function, topology::Topology, container::ContainerInterface)

Assign all agents of the container to the nodes based on the given assign_condition, this condition takes as Agent and a Node (node.id for the identifier of the node) and shall return a boolean indicating whether the agent shall be assigned to the node.

source
Mango.choose_agentMethod
choose_agent(choose_agent_function::Function, topology::Topology)

Choose the agents, which shall be assigned to the nodes. For this the choose_agent_function has to be provided. This function expects Node as argument and shall return an Agent or Agent.... The returned agent will be assigned to the node.

source
Mango.create_topologyMethod
create_topology(create_runnable)::Topology

Create a topology using the create_runnable function which is a one-argument function with an initially empty topology as argument.

Example

topology = create_topology() do topology
    agent = register(container, TopologyAgent())
    agent2 = register(container, TopologyAgent())
    agent3 = register(container, TopologyAgent())
    n1 = add_node!(topology, agent)
    n2 = add_node!(topology, agent2)
    n3 = add_node!(topology, agent3)
    add_edge!(topology, n1, n2)
    add_edge!(topology, n1, n3)
end
source
Mango.modify_topologyMethod
modify_topology(modify_runnable::Functino, topology::Topology)

Modify a topology using the modify_runnable function which is a one-argument function with the provided topology as argument.

Example

modify_topology(my_topology) do topology
    agent = register(container, TopologyAgent())
    agent2 = register(container, TopologyAgent())
    agent3 = register(container, TopologyAgent())
    n1 = add_node!(topology, agent)
    n2 = add_node!(topology, agent2)
    n3 = add_node!(topology, agent3)
    add_edge!(topology, n1, n2)
    add_edge!(topology, n1, n3)
end
source
Mango.per_nodeMethod
per_node(assign_runnable, topology)

Loops over the nodes of the topology, calls assign_runnable on every node to enable the caller to populate the node. After the loop finished the neighborhoods are created and injected into the agent.

Example

per_node(topology) do node
    add!(node, register(container, TopologyAgent()))
end
source
Mango.remove_edge!Method
remove_edge!(topology::Topology, node_id_from::Int, node_id_to::Int)

Remove the edge between node_id_from and node_id_to.

source
Mango.set_edge_state!Method
set_state!(topology::Topology, node_id_from::Int, node_id_to::Int, state::State)

Set the state of the state of the edge (node_id_from, node_id_to) to state.

source
Mango.topology_neighborsFunction
topology_neighbors(agent)

Retrieve the neighbors of the agent, represented by their addresses. These vaues will be updated when a topology is applied using per_node or create_topology.

source

Encoding/Decoding

In the following the built-in functions for encoding and decoding messages are listed.

Mango.decodeFunction
decode(buf::Vector{UInt8}, t::Type=OrderedDict{String, Any})

Decode the data in buf into an object of type t using LightBSON.bson_read.

Examples

julia> data = OrderedDict(["test" => 10])
OrderedDict{String, Int64} with 1 entry:
  "test" => 10

julia> decode(encode(data))
OrderedDict{String, Any} with 1 entry:
  "test" => 10
source
Mango.encodeMethod
encode(data::OrderedDict{String,Any})

Encode data into a UInt8 buffer using LightBSON.

Examples

julia> data = OrderedDict(["test" => 10])
OrderedDict{String, Int64} with 1 entry:
  "test" => 10

julia> encode(data)
19-element Vector{UInt8}:
 0x13
 0x00
 0x00
 0x00
 0x12
    ⋮
 0x00
 0x00
 0x00
 0x00
 0x00
source

Misc

Mango.@with_defMacro

This macro can be applied to struct definitions and adds the possibility to define default values on field declaration. In contrast to @kwdef or @with_kw, this macro will create normal parameters for construction if no default value has been provided.

Example

@with_def struct ExampleStruct
    abc::Int = 0
    def::String
end

# can be constructed as follows
es = ExampleStruct("mydefstring") # abc == 0
es = ExampleStruct("mydefstring", abc=3) # abc == 3
source