fair-acc/opencmw-cpp

[8pt,10pt] Enable (primarily REST) Client -> Webassembly

RalphSteinhagen opened this issue · 2 comments

... for the time being the OpenCMW/Client API only compiles with GCC -> should become compatible with WASM (Emscripten).

Things to be done:

  • check why LLVM/Clang has issues with some of the CTADs
  • add CMake and compiler flags to exclude known code that cannot be transpiled to WASM, ie
    • CMake checks or this, and
    • C++ code via #ifndef __EMSCRIPTEN__ etc. (primarily for ZeroMQ and httpLib dependencies)
  • update build-script and CI run-time to explicitly compile also for Emscripten as Target
  • add using the fetch API when compiled for the e emscripten target, and
  • complete/synchronise QA unit tests for native/WASM targets

Spending some more thought on this, maybe it's worthwhile to handle both cases (C++native and Emscripten client) by using coroutines and the updated circuilar_buffer API. 🤔

This would avoid having to rely on multiple threads and condition variables/mutexes by default and only implement the blocking call for client situations when it's needed/desired i.e. keeping the mechanism largely async.

The general structure should probably be kept:

  • client sending request -> circular buffer -> net-client handler/impl polling/querying whether there are new requests
  • net-client handler/impl on new data -> circular buffer -> client polling the buffer if there is new data

While the co_return and co_yield by themself are already available since long, the missing functionality is the 'generator' library where the stdlib implementation will formally come only by C++23. However, there are already some quite good pre-C++23 implementations available. I particularly like Conduit by Alecto Irene Perez that does a fine job. If there are no objections better implemented/easier to maintain solution, I'd say to stick with that.

To be checked: compatibility with WASM/Emscripten ... we may need some #if ... #else ... #endif expressions, but hopefully these could be kept to a minimum.

In terms of communication pattern that should be implemented:

  • async GET/SET
  • subscribe -- ZeroMQ this is trivial/standard for http(s), there are
    • long-polling GET -- see counter-part #231
    • SSE-based blocking GET (secondary, only if easily feasible for WASM)

The API hand handling should IMO be similar/follow how it is done for the Majordomo worker implementation:
a) the data should be (de)serialised directly into the user-provided domain objects, and
b) the de-/encoding to the appropriate wire-format (default: binary, otherwise: JSON, YAML) be done in the user-facing client.

The corresponding required IoSerialiser should work/transpile to WASM. To be checked if the unit-tests are sufficient for that.