cms-gem-daq-project / ctp7_modules

0 stars 13 forks source link

Example of templated RPC calls #149

Closed lpetre-ulb closed 4 years ago

lpetre-ulb commented 5 years ago

Brief summary of issue

In order to start the ctp7_modules migration to the templated RPC framework a minimal working example may help in addition to documentation reading.

Expected Behavior

I'm not sure this information should be saved once the first module is ported so I simply share the example in the issue.

Example

Header file common to the ctp7_modules and the DAQ machine:

#include "xhal/rpc/common.h"

/*!
 * \brief An example templated RPC module
 */
namespace TestTemplatedRPC
{

    /*!
     * \brief Define a serializable custom type
     */
    struct MyType
    {
        std::uint32_t integer;
        std::string str;

        /*!
         * \brief With its intrusive serializer
         */
        template<class Message> void serialize(Message & msg) {
            msg & integer & str;
        }
    };

    /*!
     * \brief Define a remotely callable RPC method
     *
     * Returns its \c value argument and logs its \c str argument.
     */
    struct MyMethod : public xhal::rpc::Method
    {
        MyType operator()(const MyType &value, const std::string &str) const;
    };

}

The RPC module itself:

#include "test_templated_rpc.h"

#include "xhal/rpc/register.h"

#include <libmemsvc.h>
#include "memhub.h"
#include "moduleapi.h"

memsvc_handle_t memsvc;

TestTemplatedRPC::MyType TestTemplatedRPC::MyMethod::operator()(
            const TestTemplatedRPC::MyType &value,
            const std::string &str) const
{
    LOGGER->log_message(LogManager::INFO, str);

    return value;
}

extern "C" {
    const char *module_version_key = "test_templated_rpc r0";
    int module_activity_color = 0;

    void module_init(ModuleManager *modmgr) {
        if (memhub_open(&memsvc) != 0) {
            LOGGER->log_message(LogManager::ERROR, stdsprintf("Unable to connect to memory service: %s", memsvc_get_last_error(memsvc)));
            LOGGER->log_message(LogManager::ERROR, "Unable to load module");
            return; // Do not register our functions, we depend on memsvc.
        }

        // Register the newly defined RPC method
        xhal::rpc::registerMethod<TestTemplatedRPC::MyMethod>(modmgr);
    }
}

Code calling the remote RPC method from the DAQ machine:

#include "xhal/rpc/call.h"

#include "test_templated_rpc.h"

#include <xhal/rpc/wiscrpcsvc.h>
#include <iostream>

int main(int argc, char **argv)
{
    // Exceptions are not handled in this code
    wisc::RPCSvc conn;
    conn.connect("eagle63");
    conn.load_module("test_templated_rpc", "test_templated_rpc r0");

    // The call itself
    std::cout << xhal::rpc::call<TestTemplatedRPC::MyMethod>(conn, TestTemplatedRPC::MyType{42, "MyType"}, "String to log").str << std::endl;

    return 0;
}

Context

ctp7_modules migration will start very soon.

jsturdy commented 5 years ago

@lpetre-ulb, @lmoureaux, does this architecture support overloading operator() multiple times?

lmoureaux commented 5 years ago

No.

lpetre-ulb commented 4 years ago

Migration done in #167, no new for an additional example.