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
30 constexpr DynExpProto::Common::FrequencyUnitType ToProtoFrequencyUnitType(DynExp::Units::UnitType Unit)
31 {
32 switch (Unit)
33 {
34 case DynExp::Units::UnitType::Freq_Hz: return DynExpProto::Common::FrequencyUnitType::Hz;
35 case DynExp::Units::UnitType::Wavelength_nm: return DynExpProto::Common::FrequencyUnitType::nm;
36 case DynExp::Units::UnitType::Inv_cm: return DynExpProto::Common::FrequencyUnitType::Inv_cm;
37 default: throw Util::InvalidDataException("The given unit is not supported here. Did you forget to adjust this function or the UnitType enumeration in file \"Units.h\"?");
38 }
39 }
40
47 constexpr DynExpProto::Common::IntensityUnitType ToProtoIntensityUnitType(DynExp::Units::UnitType Unit)
48 {
49 switch (Unit)
50 {
51 case DynExp::Units::UnitType::Arbitrary: return DynExpProto::Common::IntensityUnitType::Arbitrary;
52 case DynExp::Units::UnitType::LogicLevel: return DynExpProto::Common::IntensityUnitType::LogicLevel;
53 case DynExp::Units::UnitType::Counts: return DynExpProto::Common::IntensityUnitType::Counts;
54 case DynExp::Units::UnitType::Volt: return DynExpProto::Common::IntensityUnitType::Volt;
55 case DynExp::Units::UnitType::Ampere: return DynExpProto::Common::IntensityUnitType::Ampere;
56 case DynExp::Units::UnitType::Power_W: return DynExpProto::Common::IntensityUnitType::Power_W;
57 case DynExp::Units::UnitType::Power_dBm: return DynExpProto::Common::IntensityUnitType::Power_dBm;
58 default: throw Util::InvalidDataException("The given unit is not supported here. Did you forget to adjust this function or the UnitType enumeration in file \"Units.h\"?");
59 }
60 }
61
65 namespace gRPCInstrumentTasks
66 {
71 template <typename BaseInstr, std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
72 class InitTask : public BaseInstr::InitTaskType
73 {
74 protected:
78 template <typename Type>
80
81 private:
87 {
88 {
89 auto InstrParams = DynExp::dynamic_Params_cast<gRPCInstrument<BaseInstr, 0, gRPCStubs...>>(Instance.ParamsGetter());
90 auto InstrData = DynExp::dynamic_InstrumentData_cast<gRPCInstrument<BaseInstr, 0, gRPCStubs...>>(Instance.InstrumentDataGetter());
91
92 // TODO: Offer SSL credentials.
93 InstrData->StubPtrs = std::make_tuple(gRPCStubs::NewStub(grpc::CreateChannel(InstrParams->NetworkParams.MakeAddress(), grpc::InsecureChannelCredentials()))...);
94 } // InstrParams and InstrData unlocked here.
95
97 }
98
103 };
104
109 template <typename BaseInstr, std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
110 class ExitTask : public BaseInstr::ExitTaskType
111 {
112 protected:
116 template <typename Type>
118
119 private:
124 {
125 try
126 {
128
129 auto InstrData = DynExp::dynamic_InstrumentData_cast<gRPCInstrument<BaseInstr, 0, gRPCStubs...>>(Instance.InstrumentDataGetter());
130
131 InstrData->ResetStubPtrs();
132 } // InstrData unlocked here.
133 catch (...)
134 {
135 // Swallow any exception which might arise from instrument shutdown since a failure
136 // of this function is not considered a severe error.
137 }
138 }
139
144 };
145
150 template <typename BaseInstr, std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
151 class UpdateTask : public BaseInstr::UpdateTaskType
152 {
153 protected:
157 template <typename Type>
159
160 private:
168
172 virtual void UpdateFuncImpl(dispatch_tag<UpdateTask>, DynExp::InstrumentInstance& Instance) {}
173 };
174 }
175
180 template <typename gRPCStub>
181 using StubPtrType = std::shared_ptr<typename gRPCStub::Stub>;
182
187 template <typename BaseInstr, typename std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
188 class gRPCInstrumentData : public BaseInstr::InstrumentDataType
189 {
190 friend class gRPCInstrumentTasks::InitTask<BaseInstr, 0, gRPCStubs...>;
191 friend class gRPCInstrumentTasks::ExitTask<BaseInstr, 0, gRPCStubs...>;
192
193 public:
200 template <typename... ArgTs>
201 gRPCInstrumentData(ArgTs&& ...Args) : BaseInstr::InstrumentDataType(std::forward<ArgTs>(Args)...) {}
202
203 virtual ~gRPCInstrumentData() = default;
204
211 template <size_t Index>
212 auto GetStub() const noexcept { return std::get<Index>(StubPtrs); }
213
220 template <typename T>
221 auto GetStub() const noexcept { return std::get<StubPtrType<T>>(StubPtrs); }
222
223 private:
227 void ResetStubPtrs() { std::apply([](auto&... StubPtr) { (StubPtr.reset(), ...); }, StubPtrs); }
228
238
243
247 std::tuple<StubPtrType<gRPCStubs>...> StubPtrs;
248 };
249
254 template <typename BaseInstr, typename std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
255 class gRPCInstrumentParams : public BaseInstr::ParamsType
256 {
257 public:
263 : BaseInstr::ParamsType(ID, Core), NetworkParams(*this) {}
264
265 virtual ~gRPCInstrumentParams() = default;
266
270 virtual const char* GetParamClassTag() const noexcept override { return "gRPCInstrumentParams"; }
271
273
274 private:
282
287
291 virtual const DynExp::NetworkParamsExtension* GetNetworkAddressParamsChild() const noexcept override { return &NetworkParams; }
292 };
293
298 template <typename BaseInstr, typename std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
299 class gRPCInstrumentConfigurator : public BaseInstr::ConfigType
300 {
301 public:
302 using ObjectType = gRPCInstrument<BaseInstr, 0, gRPCStubs...>;
303 using ParamsType = gRPCInstrumentParams<BaseInstr, 0, gRPCStubs...>;
304
306 virtual ~gRPCInstrumentConfigurator() = default;
307
308 private:
312 virtual DynExp::ParamsBasePtrType MakeParams(DynExp::ItemIDType ID, const DynExp::DynExpCore& Core) const override { return DynExp::MakeParams<gRPCInstrumentConfigurator>(ID, Core); }
313 };
314
329 template <typename BaseInstr, typename std::enable_if_t<std::is_base_of_v<DynExp::InstrumentBase, BaseInstr>, int>, typename... gRPCStubs>
330 class gRPCInstrument : public BaseInstr
331 {
332 public:
333 using ParamsType = gRPCInstrumentParams<BaseInstr, 0, gRPCStubs...>;
334 using ConfigType = gRPCInstrumentConfigurator<BaseInstr, 0, gRPCStubs...>;
335 using InstrumentDataType = gRPCInstrumentData<BaseInstr, 0, gRPCStubs...>;
336
337 constexpr static auto Name() noexcept { return "gRPC Instrument"; }
338 constexpr static auto Category() noexcept { return "Network Instruments (Clients)"; }
339
340 protected:
344 gRPCInstrument(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType&& Params)
345 : BaseInstr(OwnerThreadID, std::move(Params)) {}
346
347 public:
348 virtual ~gRPCInstrument() {}
349
350 virtual std::string GetName() const override { return Name(); }
351 virtual std::string GetCategory() const override { return Category(); }
352
353 private:
358
363
367 virtual std::unique_ptr<DynExp::InitTaskBase> MakeInitTask() const override { return DynExp::MakeTask<gRPCInstrumentTasks::InitTask<BaseInstr, 0, gRPCStubs...>>(); }
368
372 virtual std::unique_ptr<DynExp::ExitTaskBase> MakeExitTask() const override { return DynExp::MakeTask<gRPCInstrumentTasks::ExitTask<BaseInstr, 0, gRPCStubs...>>(); }
373
377 virtual std::unique_ptr<DynExp::UpdateTaskBase> MakeUpdateTask() const override { return DynExp::MakeTask<gRPCInstrumentTasks::UpdateTask<BaseInstr, 0, gRPCStubs...>>(); }
378 };
379
389 template <typename gRPCStub, typename RequestMsgType, typename ResponseMsgType>
390 using StubFuncPtrType = grpc::Status(gRPCStub::*)(grpc::ClientContext*, const RequestMsgType&, ResponseMsgType*);
391
410 template <typename gRPCStub, typename RequestMsgType, typename ResponseMsgType>
411 inline ResponseMsgType InvokeStubFunc(StubPtrType<gRPCStub> StubPtr, StubFuncPtrType<gRPCStub, RequestMsgType, ResponseMsgType> StubFunc, const RequestMsgType& RequestMsg)
412 {
413 grpc::ClientContext Context;
414 ResponseMsgType ReplyMsg;
415
416 if (!StubPtr)
417 throw Util::InvalidStateException("A stub pointer has not been initialized yet.");
418 if (!StubFunc)
419 throw Util::InvalidArgException("StubFunc must not be nullptr.");
420
421 static const auto Timeout = std::chrono::milliseconds(2000);
422 Context.set_deadline(std::chrono::system_clock::now() + Timeout);
423
424 auto Result = (*StubPtr.*StubFunc)(&Context, RequestMsg, &ReplyMsg);
425 if (!Result.ok())
426 throw DynExpHardware::gRPCException(Result);
427
428 return ReplyMsg;
429 }
430}
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:813
Bundles several parameters to describe a network connection. Use in parameter classes.
Refer to ParamsBase::dispatch_tag.
Definition Object.h:2026
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:138
Data to operate on is invalid for a specific purpose. This indicates a corrupted data structure or fu...
Definition Exception.h:164
An operation cannot be performed currently since the related object is in an invalid state like an er...
Definition Exception.h:151
DynExp's instrument namespace contains the implementation of DynExp instruments which extend DynExp's...
constexpr DynExpProto::Common::IntensityUnitType ToProtoIntensityUnitType(DynExp::Units::UnitType Unit)
Converts a physical unit of type DynExp::Units::UnitType to a unit defined in the IntensityUnitType e...
constexpr DynExpProto::Common::FrequencyUnitType ToProtoFrequencyUnitType(DynExp::Units::UnitType Unit)
Converts a physical unit of type DynExp::Units::UnitType to a unit defined in the FrequencyUnitType e...
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.
UnitType
Units which can be used with DynExp instruments.
Definition Units.h:28
@ Ampere
Electric current in Ampere (A)
@ Inv_cm
Wavenumber in 1/cm.
@ Power_dBm
Power in dBm.
@ Arbitrary
Arbitrary units (a.u.)
@ LogicLevel
Logic level (TTL) units (1 or 0)
@ Freq_Hz
Frequency in Hz.
@ Wavelength_nm
Wavelength in nm.
@ Power_W
Power in Watt (W)
@ Volt
Voltage in Volt (V)
@ Counts
Count rate in counts per second (cps)
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:851
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.