{"id":44332382,"url":"https://github.com/bringauto/async-function-execution","last_synced_at":"2026-02-11T10:09:54.894Z","repository":{"id":316413509,"uuid":"1045503222","full_name":"bringauto/async-function-execution","owner":"bringauto","description":"Asynchronous function execution by context isolation ","archived":false,"fork":false,"pushed_at":"2025-10-30T13:10:58.000Z","size":60,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-30T15:08:58.999Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bringauto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-27T09:21:41.000Z","updated_at":"2025-09-24T12:07:05.000Z","dependencies_parsed_at":"2025-10-30T15:06:02.063Z","dependency_job_id":null,"html_url":"https://github.com/bringauto/async-function-execution","commit_stats":null,"previous_names":["bringauto/async-function-execution"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/bringauto/async-function-execution","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bringauto%2Fasync-function-execution","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bringauto%2Fasync-function-execution/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bringauto%2Fasync-function-execution/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bringauto%2Fasync-function-execution/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bringauto","download_url":"https://codeload.github.com/bringauto/async-function-execution/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bringauto%2Fasync-function-execution/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29331743,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T06:13:03.264Z","status":"ssl_error","status_checked_at":"2026-02-11T06:12:55.843Z","response_time":97,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-11T10:09:54.335Z","updated_at":"2026-02-11T10:09:54.884Z","avatar_url":"https://github.com/bringauto.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Async Function Execution\n\nA library providing the ability to call functions on a different binary over shared memory. The communication is divided to a producer and consumer.\n\n### Implementation\n\nBoth sides need to have all functions defined the same way. Example implementation:\n\n```cpp\n#include \u003cbringauto/async_function_execution/AsyncFunctionExecutor.hpp\u003e\n\nusing namespace bringauto::async_function_execution;\n\nFunctionDefinition FunctionAdd {\n\tFunctionId { 1 }, // id can be 0-255 and has to be unique\n\tReturn { int {} }, // return type of the function\n\tArguments { int {}, int {}, int {} } // individual function argument types\n};\n\nAsyncFunctionExecutor executorProducer {\n\tConfig {\n\t\t.isProducer = true, // decides the mode of the executor\n\t\t.defaultTimeout = std::chrono::seconds(1) // polling timeout (should only be used when producer)\n\t\t.functionConfigurations = structures::FunctionConfigs { {\n\t\t\t{ 1, { std::chrono::seconds(2) }}\n\t\t} }\n\t},\n\tFunctionList { // list of all functions\n\t\tFunctionAdd\n\t}\n};\n```\n\n#### Post initialization\n\nBefore using any functions, connection needs to be established using the connect function:\n\n```cpp\n// Returns -1 on a failed connection\nint rc = executorProducer.connect();\n```\n\n#### functionConfigurations\n\nThe functionConfigurations parameter accepts an unordered map representing per function configurations. Syntax:\n\n```cpp\n{\n\t{ \u003cfunction-id\u003e, { \u003ctimeout\u003e } }\n}\n```\n\nSupported parameters:\n  - timeout: replaces the default timeout value for that function (in nanoseconds)\n\n### Producer\n\nProducer is the side calling functions and waiting for a response from the consumer. If timeout is provided in config, the function will throw if it doesn't execute in time. Example of function calling:\n\n```cpp\n// the function definition and same number of expected arguments need to be provided\nint ret = executorProducer.callFunc(FunctionAdd, 1, 2, 3);\n```\n\n### Consumer\n\nConsumer is consistently polling function requests, executing the requested functions and sending the required return value back to the producer. Example function calling:\n\n```cpp\nwhile (true) {\n\t// poll for function requests and receive a function id and bytes holding the argument data\n\tauto [funcId, argBytes] = executorConsumer.pollFunction();\n\t// argument data then needs to be deserialized by providing the corresponding function definition\n\tauto [arg1, arg2, arg3] = executorConsumer.getFunctionArgs(FunctionAdd, argBytes);\n\n\t// do some work with the arguments and send a return value back to the producer\n\tint ret = arg1 + arg2 + arg3;\n\texecutorConsumer.sendReturnMessage(FunctionAdd.id, ret);\n}\n```\n\n### Non trivially copiable data types\n\nIf an argument or return type is not trivially copiable, a way of data serialization needs to be provided. This can be done simply by wraping the data type in a struct and implementing both serialize() and deserialize() functions. Example for std::string:\n\n```cpp\nstruct SerializableString final {\n\tstd::string value {};\n\tSerializableString() = default;\n\tSerializableString(std::string str) : value(std::move(str)) {}\n\n\tstd::span\u003cconst uint8_t\u003e serialize() const {\n\t\treturn std::span {reinterpret_cast\u003cconst uint8_t *\u003e(value.data()), value.size()};\n\t}\n\tvoid deserialize(std::span\u003cconst uint8_t\u003e bytes) {\n\t\tvalue = std::string {reinterpret_cast\u003cconst char *\u003e(bytes.data()), bytes.size()};\n\t}\n};\n```\n\n### Data lifetime\n\nIf a producer expects a return value where returned bytes are used directly, these bytes are valid untill the next call of the same function. If a longer lifespan is required, these bytes need to be copied, otherwise double free() errors might occur during runtime.\n\n## Requirements\n\n- [aeron](https://github.com/aeron-io/aeron)\n- [cmlib](https://github.com/cmakelib/cmakelib)\n  - the CMLIB_DIR env value has to be set\n\n\n## Build\n\n```bash\nmkdir -p _build \u0026\u0026 cd _build\ncmake ../\nmake\n```\n\n## Tests\n\n[Tests Readme](./test/README.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbringauto%2Fasync-function-execution","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbringauto%2Fasync-function-execution","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbringauto%2Fasync-function-execution/lists"}