-
Notifications
You must be signed in to change notification settings - Fork 13
Template-based RPC calls #126
Comments
During the developer meeting we have been asked to present what would be the return types for real life examples and how these types would be parsed by the client. @bdorney and @mexanick provided us this list. Here is a first attempt which is topic to further discussion :
This type can be naturally parsed in C++ and you avoid sending fillers for missing OHs : // Call the remote method
std::map<std::uint32_t, std::vector<std::uint32_t>>
multiLinkResults = conn.call<dacScanMultiLink>(...);
// Fill a ROOT tree with the data
for (auto const& singleLinkResult : multiLinkResults)
{
const uint32_t ohN = singleLinkResult.first;
const std::vector<std::uint32_t> &scanData = singleLinkResult.second;
myMagicTreeFillerFunction(ohN, dacScanData);
}
// Define what characterizes the GBT status (it's so easy to write a serializer)
struct gbt_status_t
{
bool ready;
bool wasNotReady;
bool hadUnderflow;
bool hadOverflow;
};
// We have multiple OHs, each one with gbt::GBTS_PER_OH GBTXs
std::map<std::uint32_t,
std::array<gbt_status_t, gbt::GBTS_PER_OH>> allStatuses = conn.call<getmonGBTLink>(...);
// Output the ready flag in a .csv-like format
std::cout << "# ohN gbtN readyFlag" << std::endl;
for (auto const& ohStatus : allStatuses)
{
const uint32_t ohN = ohStatus.first;
for (uint32_t gbtN=0; gbtN < gbt::GBTS_PER_OH; gbtN++)
{
std::cout << ohN << "," << gbtN << ","
<< ohStatus.second.at(gbtN).ready << std::endl;
}
}
// We have many rates
struct sbit_rates_t
{
std::vector<std::uint32_t> dacValues;
// The rates vectors keep the same definition
// That is their length is (dacMax-dacMin+1)/dacStep
std::vector<std::uint32_t> CTP7Rates;
std::vector<std::uint32_t> OHRates;
std::array<std::vector<std::uint32_t>, 24> VFATRates;
};
// Retrieve the data for all unmasked OH
std::map<std::uint32_t, sbit_rates_t> allRates = conn.call<sbitRateScan>(...);
// Since xDAQ 15 will support C++17, let's use it at our advantage
for (auto const& [ohN, rates] : allRates)
{
// Let say we want only VFAT 5 rates for every OH
for (auto const usedData : boost::combine(rates.dacValues, rates.VFATRates[5]))
{
uint32_t dacValue, rate;
boost::tie(dacValue, rate) = usedData;
std::cout << ohN << " " << dacValue << " " << rate << std::endl;
}
} These types are the first ideas which come to my mind. Of course, considering the versatility of the interface, different solutions are possible. For instance, one does not have to use a structure in |
Parallel to this issue we may want to address as well the IPBus compatibility for the RPC-based software. In this case, the |
I'm not sure I fully understand your concern here. Do you want to be able to use the RPC software on another system than the CTP7 ? So without the Zynq and its memory mapped address space ? A few months back, when I ported the CTP7 v3 firmware to the GLIB, I went with a more straightforward solution where I implemented a small wrapper which converts the the |
Yes, exactly
Yes, that was actually initial plan, just didn't have time and real need to implement. I didn't check yet the details, but I think there's also a need to wrap the update of LMDB address table method to achieve the full compatibility. I think this can be a good branching point to bring your developments to the main repository |
In fact, there is no need to bring any change to the update of LMDB table method (or any other RPC method/function). The wrapper converts the addresses on the fly, so that you can use the vanilla RPC modules.
In the upcoming weeks, I will update the v3 GLIB firmware and propose a PR to the |
Indeed, and I have long had several questions about this. For the discussion here (re: templates), the primary comment I have is that the complicated return types outlined here cry out for a different implementation, rather than trying to cram them through this interface (this comment remains even if we decide not to go this templated route) |
The migration to the templated RPC framework is now done (#167). |
This issue is about our proposal (@lmoureaux, @lpetre-ulb) to use C++ templates for type-safe RPC calls.
Links
Related issues
The following issues are related to our proposal:
RPC::RemoteException
(inheritsstd::runtime_error
) is thrown if any exception is caught on the CTP7. If available, it has information about the stack trace on the CTP7 (need to compile the modules with-g
to get meaningful stack traces).Syntax
Declaring an RPC method (remotely callable function):
RPC method implementation:
Call from DAQ PC:
Call from CTP7:
(Can also add a tiny wrapper for full symmetry with the DAQ PC)
Constraints
We work within the following limits:
rpcsvc
,RPCMsg
,RPCSvc
The text was updated successfully, but these errors were encountered: