Queries are an asynchronous means within a HELICS federation of asking for and receiving information from other federate components. A query provides the ability to evaluate the current state of a federation and typically addresses the configuration and architecture of the federation. Brokers, Federates, and Cores all have query functions. Federates are also able to define a callback for answering custom queries.
The general function looks like this:
std::string query(const std::string& target, const std::string& queryStr)
query_result = h.helicsCreateQuery(traget_string, query_string)
Each query must define a “target”, the component in the federation that is being queried. The target is either specified in terms of the relationship to the querying federate (e.g. “broker”, “core”) or by name of the federation component (e.g. “dist_system_1_fed”). The table below lists the valid query targets; if a federate happens to be named one of the target names listed below, it will not be queries by that name. For example, naming one of your brokers “broker” will prevent it being a valid target of a query by name. Instead, any federate that queries “broker” will end up targeting their broker.
queryStr is the specific data being requested; the tables below show the valid data provided by each queryable federation component. Invalid queries or targets return a json object “error” containing a code and an error message.
Answers to queries can be (in C++ data types):
- true/false [T/F]
- a single quoted string
- a vector of quoted strings delimited by
["answer1","answer"","answer3"][sv] this is a JSON compliant string vector
- a JSON string with an object [JSON]
As of HELICS 2.7.0 Queries have an optional parameter to describe a sequencing mode. There are currently two modes,
HELICS_SEQUENCING_MODE_FAST which travels along priority channels and is identical to previous versions in which all queries traveled along those channels. The other mode is
helics_sequencing_mode_ordered which travels along lower priority channels but is ordered with all other messages in the system. This can be useful in some situations where you want previous messages to be acknowledged as part of the federation before the query is run. The
global_flush query is forced to run in ordered mode at least until after it gets to the specified target.
The following queries are defined for federates. Federates may specify a callback function which allows arbitrary user defined Queries. The queries defined here are available inside of HELICS.
||the identifier of the federate [string]|
||Basic query if the federate exists in the Federation [T/F]|
||If the federate has entered init mode [T/F]|
||Current state of the federate as a string [string]|
||Current state of the federate as a string [JSON]|
||current publications of a federate [sv]|
||current subscriptions of a federate [sv]|
||current inputs of a federate [sv]|
||current endpoints of a federate [sv]|
||list of the objects this federate depends on [sv]|
||list of dependent objects [sv]|
||the current time of the federate [JSON]|
||data structure containing the filters on endpoints[JSON]|
||a graph of the dependencies in a federation [JSON]|
||a structure with all the data connections [JSON]|
||list of available queries [sv]|
||the version string of the helics library [string]|
global_flush queries are also acknowledged by federates but it is not usually recommended to run those queries on a particular federate as they are more useful at higher levels. See the
Broker queries for more description of them.
Local Federate Queries¶
The following queries are defined for federates but can only be queried on the local federate, that is, the federate making the query. Federates may specify a callback function which allows arbitrary user defined Queries.
||vector of number of the inputs that have been updated [sv]|
||names or targets of inputs that have been updated [sv]|
||values of all currently updated inputs [JSON]|
||current values of all inputs [JSON]|
||the current granted time [string]|
The following queries will be answered by a core:
version_all queries are valid but are not usually queried directly, but instead the same query is used on a broker and this query in the core is used as a building block.
The following queries will be answered by a broker:
data_flow_graph when called with the root broker as a target will generate a JSON string containing the entire structure of the federation. This can take some time to assemble since all members must be queried.
global_flush will also force the entire structure along the ordered path which can be quite a bit slower.
error codes returned by the query follow http error codes for “Not Found (404)” or “Resource Not Available (400)” or “Server Failure (500)”.
Queries that must traverse the network travel along priority paths unless specified otherwise with a sequencing mode. The calls are blocking, but they do not wait for time advancement from any federate and take priority over regular communication.
The difference between
global_state is that
current_state is generated by information contained in the component so doesn’t generate secondary queries of other components. Whereas
global_state will reach out to the other components to get up to date information on the state.
There are two basic calls in the application API as part of a federate object In addition to the call described above a second version omits the “target” specification and always queries the local federate.
std::string query(const std::string& queryStr)
There is also an asyncrhonous version (that is, non-blocking) that returns a
query_id_t that can be use in
query_id_t queryAsync(const std::string& target, const std::string& queryStr)
In the header
<helics\queryFunctions.hpp> a few helper functions are defined to vectorize query results and some utility functions to wait for a federate to enter init, or wait for a federate to join the federation.
C API and interface API’s¶
Queries in the
C API have the same valid targets and properties that can be queried but the construction of the query is slightly different. The basic operation is to create a query using
helicsQueryCreate(target,query). Once created, the target or query string can be changed with
This function returns a query object that can be used in one of the execute functions (
helicsQueryCoreExecute(), to perform the query and receive back results. The query can be called asynchronously on a federate. The target field may be empty if the query is intended to be used on a local federate, in which case the target is assumed to be the federate itself.
A query must be freed after use