joque
task orchestration library
joque Namespace Reference

MIT License. More...

Namespaces

 bits
 MIT License.
 

Classes

struct  edge_content
 
struct  node_content
 
class  exec_coro
 Coroutine representing one execution of entire task set. More...
 
class  exec_visitor
 Execution visitor interface, used by execution. More...
 
struct  job_iface
 Job interface used by task and execution. More...
 
struct  job
 Implementation of job interface, storing the specific job type that shall be used. More...
 
struct  job_ptr
 Custom unique_ptr wrapper that simplifies syntax of tasks. More...
 
struct  out_tag
 Baseclass for tagging system. More...
 
struct  out
 Tags a filesystem path as an output filename. More...
 
class  print_exec_visitor
 Default visitor for execution. Prints information on stdout or stderr. More...
 
struct  process
 Job-friendly structure for definition of subprocess to be executed. More...
 
struct  job_traits< process >
 Traits overload so that process can be used in combination with the library. More...
 
struct  run_record
 Record storing information about a run of one task, produced during single execution once for each task. More...
 
struct  exec_record
 Record of execution of entire task set. More...
 
struct  output_chunk
 
struct  run_result
 TODO: hide this Result of single traits run call. More...
 
struct  inval_result
 
struct  resource
 Abstraction to model resource used by tasks. More...
 
struct  task
 Single task that should be executed by the system. More...
 
struct  task_set
 A set of tasks that contains either tasks or another sets. More...
 
struct  job_traits
 Default job traits for all types. More...
 

Typedefs

using dag_edge = bits::gedge< edge_content >
 
using dag_node = bits::gnode< node_content, dag_edge >
 
using dag = bits::graph< dag_node >
 DAG used to store data in single execution of tasks. More...
 
using tp = std::chrono::time_point< std::chrono::system_clock >
 
template<typename T >
using ref_vec = std::vector< std::reference_wrapper< const T > >
 

Enumerations

enum class  ekind : uint8_t {
  AFTER ,
  INVALIDATED_BY ,
  REQUIRES
}
 
enum class  inval : uint8_t {
  VALID ,
  INVALID ,
  UNKNOWN
}
 
enum class  run_status : uint8_t {
  OK ,
  SKIP ,
  DEPF ,
  FAIL
}
 

Functions

std::string_view to_sv (const ekind &e)
 
template<ekind Kind, typename Edges >
auto filter_edges (Edges &e)
 
template<typename Node , typename... Args>
void add_edge (Node &source, Node &target, Args &&... args)
 
std::string_view to_sv (const inval &k)
 
void insert_set (dag &dag, const task_set &ts, const std::string &filter)
 
exec_coro exec (const task_set &ts, unsigned thread_count=std::thread::hardware_concurrency(), const std::string &filter="", exec_visitor &vis=PRINT_VISITOR)
 Runs execution of tasks within one taskset. More...
 
exec_coro exec (dag g, unsigned thread_count=std::thread::hardware_concurrency(), exec_visitor &vis=PRINT_VISITOR)
 Overload of exec which uses dag as an input instead of task set. More...
 
void format_nested (std::ostream &os, std::string_view indent, const std::list< output_chunk > &output)
 Assumes that msg is multiline message, streams each line into os, and prefixes each line with indent string. More...
 
void format_run_end (std::ostream &os, const exec_record &erec, const run_record &rec)
 Formats information about record rec and streams it into os. More...
 
void format_exec_end (std::ostream &os, const exec_record &erec)
 
void format_status (std::ostream &os, const exec_record &erec, std::string_view name)
 
void format_dag (const dag &d, const std::function< void(std::string_view) > &f)
 
void print_dag (std::ostream &os, const dag &d)
 
void to_json (nlohmann::json &j, const output_chunk &rec)
 
void to_json (nlohmann::json &j, const run_record &rec)
 
void to_json (nlohmann::json &j, const exec_record &rec)
 
void generate_junit_xml (const std::filesystem::path &p, const std::string &ts_name, const exec_record &exec_rec)
 Generates JUnit XML file, expects that execution record represents some form of test execution. More...
 
void generate_junit_xml (std::ostream &os, const std::string &ts_name, const exec_record &exec_rec)
 Overload of generate_junit_xml that uses ostream instead of filename. More...
 
std::string_view to_sv (const run_status &s)
 
void map (std::convertible_to< run_record > auto &rec, auto &&f)
 
std::chrono::seconds runtime_sum (const exec_record &erec)
 
void map (std::convertible_to< exec_record > auto &rec, auto &&f)
 
void map (std::convertible_to< output_chunk > auto &rec, auto &&f)
 
void insert (auto &res, output_chunk::type_e type, std::string data)
 
void insert_std (auto &res, std::string data)
 
void insert_err (auto &res, std::string data)
 
template<typename T , typename Fun >
 requires (std::same_as< std::remove_cvref_t< T >, task_set >) void for_each_task(T &ts
 Recursively executes function f for each task in set ts. More...
 
void for_each_add_dep (task_set &ts, const task &dep)
 Recursively adds dependency on dep for each task in ts, except for dep itself. More...
 
void add_dep_to_each (task &t, const task_set &ts)
 Recursively adds dependency on each task in ts to task t, except for t itself. More...
 
void run_each_after (task_set &ts, const task &t)
 Recursively adds run after relationship so that all tasks in ts are run after t. More...
 
void run_after_all_of (task &t, const task_set &ts)
 Recursively adds run after relationship so that task t is run after all tasks in set ts. More...
 
void invalidated_by_all_of (task &t, const task_set &ts)
 
template<typename T , typename Fun >
void for_each_task_impl (T &ts, Fun &&f, const std::string &prefix)
 

Variables

print_exec_visitor PRINT_VISITOR
 Global instance of print visitor used as default argument for exec More...
 
Fun && f
 

Detailed Description

MIT License.

Copyright (c) 2025 Jan Veverak Koniarik

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Class Documentation

◆ joque::edge_content

struct joque::edge_content
+ Collaboration diagram for joque::edge_content:
Class Members
dag_node & source
dag_node & target
ekind kind

◆ joque::node_content

struct joque::node_content
+ Collaboration diagram for joque::node_content:
Class Members
string name Full path-name of the task.
const task & t Reference to the task.
inval invalidated Node validation status.
bool started Sets to true once the task is scheduled for execution.
bool done Sets to done if the task finished it's execution (correctly or incorrectly)
bool failed Sets to fail if the task failed during execution.

◆ joque::run_record

struct joque::run_record

Record storing information about a run of one task, produced during single execution once for each task.

Note that this valid only as long as the input task set was not modified.

+ Collaboration diagram for joque::run_record:
Class Members
reference_wrapper< const task > t Executed task.
string name Full name of the task.
run_status status
int retcode Return code of the execution. Assumes that 0 means success.
tp start Start time of the execution.
tp end End time of the execution.
list< output_chunk > output

◆ joque::exec_record

struct joque::exec_record

Record of execution of entire task set.

Is valid only as long as the original task set was not modified.

+ Collaboration diagram for joque::exec_record:
Class Members
map< run_status, size_t > stats
size_t total_count Total number of jobs.
vector< run_record > runs Run record for each finished task in the set.

◆ joque::run_result

struct joque::run_result

TODO: hide this Result of single traits run call.

Information is stored in run record.

+ Collaboration diagram for joque::run_result:
Class Members
int retcode Return code of the run, 0 implies success.
list< output_chunk > output
string log

◆ joque::inval_result

struct joque::inval_result
+ Collaboration diagram for joque::inval_result:
Class Members
bool invalidated
string log

◆ joque::resource

struct joque::resource

Abstraction to model resource used by tasks.

Out of all tasks that reference single resource, only one may be executed at any point in time.

+ Collaboration diagram for joque::resource:
Class Members
string name

◆ joque::task

struct joque::task

Single task that should be executed by the system.

+ Collaboration diagram for joque::task:
Class Members
job_ptr job Job being executed for the task.
ref_vec< task > depends_on Dependencies of the task - all of these should be executed before this task.

In case any of these is invalidated, this task is also invalidated.

ref_vec< task > run_after Tasks that should be executed before this task.

(depends_on task are implicitly included)

ref_vec< task > invalidated_by Tasks which invalidation also invalidates this task.
ref_vec< resource > resources Resources used by this task, only one task can access any resource at single point in time.
bool hidden In case this is set to true, this task should not be visible in standard reports.

◆ joque::task_set

struct joque::task_set

A set of tasks that contains either tasks or another sets.

This forms a tree representing the entire task set.

Convention is that names inside the structure are concatenated to form a full path. Task x in root set is referred as //x. Task y in subset z is referred as //z/y.

+ Collaboration diagram for joque::task_set:
Class Members
map< string, task > tasks Tasks of this set.
map< string, task_set > sets Subsets of this set.

Typedef Documentation

◆ dag_edge

◆ dag_node

◆ dag

using joque::dag = typedef bits::graph< dag_node >

DAG used to store data in single execution of tasks.

◆ tp

using joque::tp = typedef std::chrono::time_point< std::chrono::system_clock >

◆ ref_vec

template<typename T >
using joque::ref_vec = typedef std::vector< std::reference_wrapper< const T > >

Enumeration Type Documentation

◆ ekind

enum joque::ekind : uint8_t
strong
Enumerator
AFTER 
INVALIDATED_BY 
REQUIRES 

◆ inval

enum joque::inval : uint8_t
strong
Enumerator
VALID 
INVALID 
UNKNOWN 

◆ run_status

enum joque::run_status : uint8_t
strong
Enumerator
OK 
SKIP 
DEPF 
FAIL 

Function Documentation

◆ to_sv() [1/3]

std::string_view joque::to_sv ( const ekind e)

◆ filter_edges()

template<ekind Kind, typename Edges >
auto joque::filter_edges ( Edges &  e)

◆ add_edge()

template<typename Node , typename... Args>
void joque::add_edge ( Node &  source,
Node &  target,
Args &&...  args 
)

◆ to_sv() [2/3]

std::string_view joque::to_sv ( const inval k)

◆ insert_set()

void joque::insert_set ( dag dag,
const task_set ts,
const std::string &  filter 
)

◆ exec() [1/2]

exec_coro joque::exec ( const task_set ts,
unsigned  thread_count = std::thread::hardware_concurrency(),
const std::string &  filter = "",
exec_visitor vis = PRINT_VISITOR 
)

Runs execution of tasks within one taskset.

This returns coroutine handling the execution process. Withing it lives a thread pool that pararelly executes all tasks in the task_set. Tasks are limited only to those that pass the filter, or their dependencies.

In case any task has defined dependencies on resource, only one task at a time would be executed for each resource.

During the execution, the input task set shall not be modified and any modification might result in undefined behavior. After the execution, the produced records structure is valid only for as long as the input task_set was not modified.

In case 1...n threads are requested, the tasks are executed inside those worker threads and control thread is not used for execution. In case the thread count is 0, all jobs are executed within the control thread itself.

Parameters
tsInput task set to process
thread_countNumber of threads to use
filterString filtering out tasks that either match it, or are dependencies of matched tasks
visVisitor called by the execution on various events

◆ exec() [2/2]

exec_coro joque::exec ( dag  g,
unsigned  thread_count = std::thread::hardware_concurrency(),
exec_visitor vis = PRINT_VISITOR 
)

Overload of exec which uses dag as an input instead of task set.

It's not recommended to use it, but it exists in case users want to customize the dag.

◆ format_nested()

void joque::format_nested ( std::ostream &  os,
std::string_view  indent,
const std::list< output_chunk > &  output 
)

Assumes that msg is multiline message, streams each line into os, and prefixes each line with indent string.

◆ format_run_end()

void joque::format_run_end ( std::ostream &  os,
const exec_record erec,
const run_record rec 
)

Formats information about record rec and streams it into os.

◆ format_exec_end()

void joque::format_exec_end ( std::ostream &  os,
const exec_record erec 
)

◆ format_status()

void joque::format_status ( std::ostream &  os,
const exec_record erec,
std::string_view  name 
)

◆ format_dag()

void joque::format_dag ( const dag d,
const std::function< void(std::string_view) > &  f 
)

◆ print_dag()

void joque::print_dag ( std::ostream &  os,
const dag d 
)

◆ to_json() [1/3]

void joque::to_json ( nlohmann::json &  j,
const output_chunk rec 
)

◆ to_json() [2/3]

void joque::to_json ( nlohmann::json &  j,
const run_record rec 
)

◆ to_json() [3/3]

void joque::to_json ( nlohmann::json &  j,
const exec_record rec 
)

◆ generate_junit_xml() [1/2]

void joque::generate_junit_xml ( const std::filesystem::path &  p,
const std::string &  ts_name,
const exec_record exec_rec 
)

Generates JUnit XML file, expects that execution record represents some form of test execution.

Parameters
poutput file to which the XML should be generated
ts_namename of the test suite
exec_recexecution record

◆ generate_junit_xml() [2/2]

void joque::generate_junit_xml ( std::ostream &  os,
const std::string &  ts_name,
const exec_record exec_rec 
)

Overload of generate_junit_xml that uses ostream instead of filename.

Parameters
osoutput stream to which the XML should be generated
ts_namename of the test suite
exec_recexecution record

◆ to_sv() [3/3]

std::string_view joque::to_sv ( const run_status s)

◆ map() [1/3]

void joque::map ( std::convertible_to< run_record > auto &  rec,
auto &&  f 
)

References f.

◆ runtime_sum()

std::chrono::seconds joque::runtime_sum ( const exec_record erec)

◆ map() [2/3]

void joque::map ( std::convertible_to< exec_record > auto &  rec,
auto &&  f 
)

References f, and to_sv().

◆ map() [3/3]

void joque::map ( std::convertible_to< output_chunk > auto &  rec,
auto &&  f 
)

References f.

◆ insert()

void joque::insert ( auto &  res,
output_chunk::type_e  type,
std::string  data 
)

◆ insert_std()

void joque::insert_std ( auto &  res,
std::string  data 
)

◆ insert_err()

void joque::insert_err ( auto &  res,
std::string  data 
)

◆ requires()

template<typename T , typename Fun >
joque::requires ( std::same_as< std::remove_cvref_t< T >, task_set ) &

Recursively executes function f for each task in set ts.

Function is given full name of the task and reference to the task. Respects qualifiers of the input task set.

◆ for_each_add_dep()

void joque::for_each_add_dep ( task_set ts,
const task dep 
)

Recursively adds dependency on dep for each task in ts, except for dep itself.

◆ add_dep_to_each()

void joque::add_dep_to_each ( task t,
const task_set ts 
)

Recursively adds dependency on each task in ts to task t, except for t itself.

◆ run_each_after()

void joque::run_each_after ( task_set ts,
const task t 
)

Recursively adds run after relationship so that all tasks in ts are run after t.

◆ run_after_all_of()

void joque::run_after_all_of ( task t,
const task_set ts 
)

Recursively adds run after relationship so that task t is run after all tasks in set ts.

◆ invalidated_by_all_of()

void joque::invalidated_by_all_of ( task t,
const task_set ts 
)

◆ for_each_task_impl()

template<typename T , typename Fun >
void joque::for_each_task_impl ( T &  ts,
Fun &&  f,
const std::string &  prefix 
)

References f.

Variable Documentation

◆ PRINT_VISITOR

print_exec_visitor joque::PRINT_VISITOR
inline

Global instance of print visitor used as default argument for exec

◆ f

Fun && joque::f
Initial value:
{
for_each_task_impl( ts, f, "/" )
Fun && f
Definition: task.hpp:93
void for_each_task_impl(T &ts, Fun &&f, const std::string &prefix)
Definition: task.hpp:114