DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Loading...
Searching...
No Matches
gRPCInstrument.h
Go to the documentation of this file.
1// This file is part of DynExp.
2
9#pragma once
10
11#include "stdafx.h"
12#include "DynExpCore.h"
15
16#include "Common.pb.h"
17#include "Common.grpc.pb.h"
18
19namespace DynExpInstr
20{
21 template <typename BaseInstr, typename std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
22 class gRPCInstrument;
23
27 namespace gRPCInstrumentTasks
28 {
33 template <typename BaseInstr, std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
34 class InitTask : public BaseInstr::InitTaskType
35 {
36 protected:
40 template <typename Type>
42
43 private:
49 {
50 {
51 auto InstrParams = DynExp::dynamic_Params_cast<gRPCInstrument<BaseInstr, 0, gRPCStubs...>>(Instance.ParamsGetter());
52 auto InstrData = DynExp::dynamic_InstrumentData_cast<gRPCInstrument<BaseInstr, 0, gRPCStubs...>>(Instance.InstrumentDataGetter());
53
54 // TODO: Offer SSL credentials.
55 InstrData->StubPtrs = std::make_tuple(gRPCStubs::NewStub(grpc::CreateChannel(InstrParams->NetworkParams.MakeAddress(), grpc::InsecureChannelCredentials()))...);
56 } // InstrParams and InstrData unlocked here.
57
59 }
60
65 };
66
71 template <typename BaseInstr, std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
72 class ExitTask : public BaseInstr::ExitTaskType
73 {
74 protected:
78 template <typename Type>
80
81 private:
86 {
87 try
88 {
90
91 auto InstrData = DynExp::dynamic_InstrumentData_cast<gRPCInstrument<BaseInstr, 0, gRPCStubs...>>(Instance.InstrumentDataGetter());
92
93 InstrData->ResetStubPtrs();
94 } // InstrData unlocked here.
95 catch (...)
96 {
97 // Swallow any exception which might arise from instrument shutdown since a failure
98 // of this function is not considered a severe error.
99 }
100 }
101
106 };
107
112 template <typename BaseInstr, std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
113 class UpdateTask : public BaseInstr::UpdateTaskType
114 {
115 protected:
119 template <typename Type>
121
122 private:
130
134 virtual void UpdateFuncImpl(dispatch_tag<UpdateTask>, DynExp::InstrumentInstance& Instance) {}
135 };
136 }
137
142 template <typename gRPCStub>
143 using StubPtrType = std::shared_ptr<typename gRPCStub::Stub>;
144
149 template <typename BaseInstr, typename std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
150 class gRPCInstrumentData : public BaseInstr::InstrumentDataType
151 {
152 friend class gRPCInstrumentTasks::InitTask<BaseInstr, 0, gRPCStubs...>;
153 friend class gRPCInstrumentTasks::ExitTask<BaseInstr, 0, gRPCStubs...>;
154
155 public:
162 template <typename... ArgTs>
163 gRPCInstrumentData(ArgTs&& ...Args) : BaseInstr::InstrumentDataType(std::forward<ArgTs>(Args)...) {}
164
165 virtual ~gRPCInstrumentData() = default;
166
173 template <size_t Index>
174 auto GetStub() const noexcept { return std::get<Index>(StubPtrs); }
175
182 template <typename T>
183 auto GetStub() const noexcept { return std::get<StubPtrType<T>>(StubPtrs); }
184
185 private:
189 void ResetStubPtrs() { std::apply([](auto&... StubPtr) { (StubPtr.reset(), ...); }, StubPtrs); }
190
200
205
209 std::tuple<StubPtrType<gRPCStubs>...> StubPtrs;
210 };
211
216 template <typename BaseInstr, typename std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
217 class gRPCInstrumentParams : public BaseInstr::ParamsType
218 {
219 public:
225 : BaseInstr::ParamsType(ID, Core), NetworkParams(*this) {}
226
227 virtual ~gRPCInstrumentParams() = default;
228
232 virtual const char* GetParamClassTag() const noexcept override { return "gRPCInstrumentParams"; }
233
235
236 private:
244
249
253 virtual const DynExp::NetworkParamsExtension* GetNetworkAddressParamsChild() const noexcept override { return &NetworkParams; }
254 };
255
260 template <typename BaseInstr, typename std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
261 class gRPCInstrumentConfigurator : public BaseInstr::ConfigType
262 {
263 public:
264 using ObjectType = gRPCInstrument<BaseInstr, 0, gRPCStubs...>;
265 using ParamsType = gRPCInstrumentParams<BaseInstr, 0, gRPCStubs...>;
266
268 virtual ~gRPCInstrumentConfigurator() = default;
269
270 private:
274 virtual DynExp::ParamsBasePtrType MakeParams(DynExp::ItemIDType ID, const DynExp::DynExpCore& Core) const override { return DynExp::MakeParams<gRPCInstrumentConfigurator>(ID, Core); }
275 };
276
291 template <typename BaseInstr, typename std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
292 class gRPCInstrument : public BaseInstr
293 {
294 public:
295 using ParamsType = gRPCInstrumentParams<BaseInstr, 0, gRPCStubs...>;
296 using ConfigType = gRPCInstrumentConfigurator<BaseInstr, 0, gRPCStubs...>;
297 using InstrumentDataType = gRPCInstrumentData<BaseInstr, 0, gRPCStubs...>;
298
299 constexpr static auto Name() noexcept { return "gRPC Instrument"; }
300 constexpr static auto Category() noexcept { return "Network Instruments (Clients)"; }
301
302 protected:
306 gRPCInstrument(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType&& Params)
307 : BaseInstr(OwnerThreadID, std::move(Params)) {}
308
309 public:
310 virtual ~gRPCInstrument() {}
311
312 virtual std::string GetName() const override { return Name(); }
313 virtual std::string GetCategory() const override { return Category(); }
314
315 private:
320
325
329 virtual std::unique_ptr<DynExp::InitTaskBase> MakeInitTask() const override { return DynExp::MakeTask<gRPCInstrumentTasks::InitTask<BaseInstr, 0, gRPCStubs...>>(); }
330
334 virtual std::unique_ptr<DynExp::ExitTaskBase> MakeExitTask() const override { return DynExp::MakeTask<gRPCInstrumentTasks::ExitTask<BaseInstr, 0, gRPCStubs...>>(); }
335
339 virtual std::unique_ptr<DynExp::UpdateTaskBase> MakeUpdateTask() const override { return DynExp::MakeTask<gRPCInstrumentTasks::UpdateTask<BaseInstr, 0, gRPCStubs...>>(); }
340 };
341
351 template <typename gRPCStub, typename RequestMsgType, typename ResponseMsgType>
352 using StubFuncPtrType = grpc::Status(gRPCStub::*)(grpc::ClientContext*, const RequestMsgType&, ResponseMsgType*);
353
372 template <typename gRPCStub, typename RequestMsgType, typename ResponseMsgType>
373 inline ResponseMsgType InvokeStubFunc(StubPtrType<gRPCStub> StubPtr, StubFuncPtrType<gRPCStub, RequestMsgType, ResponseMsgType> StubFunc, const RequestMsgType& RequestMsg)
374 {
375 grpc::ClientContext Context;
376 ResponseMsgType ReplyMsg;
377
378 if (!StubPtr)
379 throw Util::InvalidStateException("A stub pointer has not been initialized yet.");
380 if (!StubFunc)
381 throw Util::InvalidArgException("StubFunc must not be nullptr.");
382
383 static const auto Timeout = std::chrono::milliseconds(2000);
384 Context.set_deadline(std::chrono::system_clock::now() + Timeout);
385
386 auto Result = (*StubPtr.*StubFunc)(&Context, RequestMsg, &ReplyMsg);
387 if (!Result.ok())
388 throw DynExpHardware::gRPCException(Result);
389
390 return ReplyMsg;
391 }
392}
Implementation of a data stream meta instrument and of data streams input/output devices might work o...
Defines DynExp's core module as an interface between the UI and DynExp objects.
Implementation of a hardware adapter to communicate over TCP sockets using gRPC.
Defines an exception caused by an operation involving the gRPC library and communication over a TCP s...
Configurator class for gRPCInstrument.
virtual DynExp::ParamsBasePtrType MakeParams(DynExp::ItemIDType ID, const DynExp::DynExpCore &Core) const override
Override to make derived classes call DynExp::MakeParams with the correct configurator type derived f...
Data class for gRPCInstrument.
virtual ~gRPCInstrumentData()=default
virtual void ResetImpl(DynExp::InstrumentDataBase::dispatch_tag< gRPCInstrumentData >)
Refer to DynExp::InstrumentDataBase::Reset(). Using tag dispatch mechanism to ensure that ResetImpl()...
gRPCInstrumentData(ArgTs &&...Args)
Constructs a gRPCInstrumentData instance and forwards all arguments passed to the constructor to the ...
auto GetStub() const noexcept
Returns a stub pointer this gRPCInstrument uses selected by the stub index in the gRPCStubs list of g...
void ResetImpl(DynExp::InstrumentDataBase::dispatch_tag< typename BaseInstr::InstrumentDataType >) override final
Refer to DynExp::InstrumentDataBase::Reset(). Using tag dispatch mechanism to ensure that ResetImpl()...
void ResetStubPtrs()
Sets all pointers contained in StubPtrs to nullptr.
std::tuple< StubPtrType< gRPCStubs >... > StubPtrs
Tuple of pointers to all the stubs this gRPCInstrument uses.
Parameter class for gRPCInstrument.
virtual ~gRPCInstrumentParams()=default
gRPCInstrumentParams(DynExp::ItemIDType ID, const DynExp::DynExpCore &Core)
Constructs the parameters for a gRPCInstrument instance.
DynExp::NetworkParamsExtension NetworkParams
Network address of the gRPC server to connect to.
virtual const char * GetParamClassTag() const noexcept override
This function is intended to be overridden once in each derived class returning the name of the respe...
virtual const DynExp::NetworkParamsExtension * GetNetworkAddressParamsChild() const noexcept override
Returns the network address parameters of a derived gRPC instrument. Override GetNetworkAddressParams...
virtual void ConfigureParamsImpl(DynExp::InstrumentParamsBase::dispatch_tag< gRPCInstrumentParams >)
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
void ConfigureParamsImpl(DynExp::InstrumentParamsBase::dispatch_tag< typename BaseInstr::ParamsType >) override final
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
Defines a task for deinitializing an instrument within an instrument inheritance hierarchy....
virtual void ExitFuncImpl(dispatch_tag< ExitTask >, DynExp::InstrumentInstance &Instance)
Deinitializes the respective instrument within the instrument inheritance hierarchy....
void ExitFuncImpl(dispatch_tag< typename BaseInstr::ExitTaskType >, DynExp::InstrumentInstance &Instance) override final
Deinitializes the respective instrument within the instrument inheritance hierarchy....
Defines a task for initializing an instrument within an instrument inheritance hierarchy....
virtual void InitFuncImpl(dispatch_tag< InitTask< BaseInstr, 0, gRPCStubs... > >, DynExp::InstrumentInstance &Instance)
Initializes the respective instrument within the instrument inheritance hierarchy....
void InitFuncImpl(dispatch_tag< typename BaseInstr::InitTaskType >, DynExp::InstrumentInstance &Instance) override final
Initializes the respective instrument within the instrument inheritance hierarchy....
Defines a task for updating an instrument within an instrument inheritance hierarchy....
void UpdateFuncImpl(dispatch_tag< typename BaseInstr::UpdateTaskType >, DynExp::InstrumentInstance &Instance) override final
Updates the respective instrument within the instrument inheritance hierarchy. Call UpdateFuncImpl() ...
Meta instrument template for transforming meta instruments into network instruments,...
void ResetImpl(DynExp::Object::dispatch_tag< BaseInstr >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
virtual void ResetImpl(DynExp::Object::dispatch_tag< gRPCInstrument >)
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
virtual std::string GetCategory() const override
Returns the category of this Object type.
virtual std::unique_ptr< DynExp::InitTaskBase > MakeInitTask() const override
Factory function for an init task (InitTaskBase). Override to define the desired initialization task ...
static constexpr auto Category() noexcept
Every derived class has to redefine this function.
virtual std::unique_ptr< DynExp::UpdateTaskBase > MakeUpdateTask() const override
Factory function for an update task (UpdateTaskBase). Override to define the desired update task in d...
virtual std::string GetName() const override
Returns the name of this Object type.
static constexpr auto Name() noexcept
Every derived class has to redefine this function.
gRPCInstrument(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType &&Params)
Constructs an instrument instance.
virtual std::unique_ptr< DynExp::ExitTaskBase > MakeExitTask() const override
Factory function for an exit task (ExitTaskBase). Override to define the desired deinitialization tas...
DynExp's core class acts as the interface between the user interface and DynExp's internal data like ...
Definition DynExpCore.h:127
Refer to DynExp::ParamsBase::dispatch_tag.
Refer to DynExp::ParamsBase::dispatch_tag.
Refer to ParamsBase::dispatch_tag.
Definition Instrument.h:146
Defines data for a thread belonging to a InstrumentBase instance. Refer to RunnableInstance.
Definition Instrument.h:772
Bundles several parameters to describe a network connection. Use in parameter classes.
Refer to ParamsBase::dispatch_tag.
Definition Object.h:2018
Tag for function dispatching mechanism within this class used when derived classes are not intended t...
Definition Object.h:349
Refer to DynExp::ParamsBase::dispatch_tag.
An invalid argument like a null pointer has been passed to a function.
Definition Exception.h:137
An operation cannot be performed currently since the related object is in an invalid state like an er...
Definition Exception.h:150
DynExp's instrument namespace contains the implementation of DynExp instruments which extend DynExp's...
ResponseMsgType InvokeStubFunc(StubPtrType< gRPCStub > StubPtr, StubFuncPtrType< gRPCStub, RequestMsgType, ResponseMsgType > StubFunc, const RequestMsgType &RequestMsg)
Invokes a gRPC stub function as a remote procedure call. Waits for a fixed amount of time (2 seconds)...
std::shared_ptr< typename gRPCStub::Stub > StubPtrType
Alias for a pointer to a gRPC stub.
grpc::Status(gRPCStub::*)(grpc::ClientContext *, const RequestMsgType &, ResponseMsgType *) StubFuncPtrType
Alias for a pointer to a gRPC stub function, which can be invoked as a remote procedure call.
auto dynamic_InstrumentData_cast(Util::SynchronizedPointer< From > &&InstrumentDataPtr)
Casts the data base class From into a derived InstrumentBase's (To) data class keeping the data locke...
Definition Instrument.h:810
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
Definition Object.h:1807
size_t ItemIDType
ID type of objects/items managed by DynExp.
std::unique_ptr< TaskT > MakeTask(ArgTs &&...Args)
Factory function to create a task to be enqueued in an instrument's task queue.
Definition Instrument.h:63
T::ParamsType * dynamic_Params_cast(ParamsBasePtrType::element_type *Params)
Casts the parameter base class to a derived Object's parameter class.
Definition Object.h:1835
Accumulates include statements to provide a precompiled header.