DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Loading...
Searching...
No Matches
HardwareAdaptergRPC.h
Go to the documentation of this file.
1// This file is part of DynExp.
2
9#pragma once
10
11#include "stdafx.h"
13
14namespace DynExpHardware
15{
16 template <typename gRPCStub>
17 class gRPCHardwareAdapter;
18
24 {
28 static constexpr auto UNIMPLEMENTED_ErrorMsg = "The connected gRPC server does not implement the called gRPC stub function. Check the server configuration.";
29
30 public:
36 gRPCException(const grpc::Status Result, const std::source_location Location = std::source_location::current()) noexcept;
37 };
38
43 template <typename gRPCStub>
44 class gRPCHardwareAdapterParams : public DynExp::HardwareAdapterParamsBase
45 {
46 public:
52 : HardwareAdapterParamsBase(ID, Core), NetworkParams(*this) {}
53
54 virtual ~gRPCHardwareAdapterParams() = default;
55
56 virtual const char* GetParamClassTag() const noexcept override { return "gRPCHardwareAdapterParams"; }
57
59
60 private:
63 };
64
68 template <typename gRPCStub>
70 {
71 public:
74
77
78 private:
79 virtual DynExp::ParamsBasePtrType MakeParams(DynExp::ItemIDType ID, const DynExp::DynExpCore& Core) const override { return DynExp::MakeParams<gRPCHardwareAdapterConfigurator>(ID, Core); }
80 };
81
88 template <typename gRPCStub>
90 {
91 public:
94 using gRPCStubType = gRPCStub;
95
96 constexpr static auto Name() noexcept { return "gRPC Hardware Adapter"; }
97 constexpr static auto Category() noexcept { return "Communication"; }
98
99 gRPCHardwareAdapter(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType&& Params)
100 : HardwareAdapterBase(OwnerThreadID, std::move(Params)) {}
102
103 virtual std::string GetName() const override { return Name(); }
104 virtual std::string GetCategory() const override { return Category(); }
105
106 protected:
111
116 typename gRPCStub::Stub& GetStubUnsafe() const;
117
124 void CheckError(const grpc::Status Result, const std::source_location Location = std::source_location::current()) const;
125
130 bool IsOpenedUnsafe() const noexcept { return StubPtr.get(); }
132
133 private:
136
137 void EnsureReadyStateChild() override final;
138 bool IsReadyChild() const override final;
139 bool IsConnectedChild() const noexcept override final;
140
145
150 void OpenUnsafe();
151
155 void CloseUnsafe();
157
162
165 virtual void OpenUnsafeChild() {}
166
170 virtual void CloseUnsafeChild() {}
172
173 std::unique_ptr<typename gRPCStub::Stub> StubPtr;
174 };
175
176 template <typename gRPCStub>
178 {
179 // Not locking, since the object is being destroyed. This should be inherently thread-safe.
180 CloseUnsafe();
181 }
182
183 template <typename gRPCStub>
184 typename gRPCStub::Stub& gRPCHardwareAdapter<gRPCStub>::GetStubUnsafe() const
185 {
186 if (!IsOpenedUnsafe())
187 ThrowExceptionUnsafe(std::make_exception_ptr(Util::NotAvailableException("The gRPC stub is not connected yet.", Util::ErrorType::Error)));
188
189 return *StubPtr;
190 }
191
192 template <typename gRPCStub>
193 void gRPCHardwareAdapter<gRPCStub>::CheckError(const grpc::Status Result, const std::source_location Location) const
194 {
195 if (Result.ok())
196 return;
197
198 // AcquireLock() has already been called by an (in)direct caller of this function.
199 ThrowExceptionUnsafe(std::make_exception_ptr(gRPCException(Result, Location)));
200 }
201
202 template <typename gRPCStub>
204 {
205 // auto lock = AcquireLock(); not necessary here, since DynExp ensures that Object::Reset() can only
206 // be called if respective object is not in use.
207
208 CloseUnsafe();
209
211 }
212
213 template <typename gRPCStub>
215 {
216 auto lock = AcquireLock(HardwareOperationTimeout);
217
218 OpenUnsafe();
219 }
220
221 template <typename gRPCStub>
223 {
224 auto lock = AcquireLock(HardwareOperationTimeout);
225
226 auto Exception = GetExceptionUnsafe();
228
229 return IsOpenedUnsafe();
230 }
231
232 template <typename gRPCStub>
234 {
235 try
236 {
237 auto lock = AcquireLock(HardwareOperationTimeout);
238
239 return IsOpenedUnsafe();
240 }
241 catch (...)
242 {
243 return false;
244 }
245 }
246
247 template <typename gRPCStub>
249 {
250 if (IsOpenedUnsafe())
251 return;
252
253 auto DerivedParams = dynamic_Params_cast<gRPCHardwareAdapter>(GetParams());
254
255 // TODO: Offer SSL credentials.
256 StubPtr = gRPCStub::NewStub(grpc::CreateChannel(DerivedParams->NetworkParams.MakeAddress(), grpc::InsecureChannelCredentials()));
257
258 OpenUnsafeChild();
259 }
260
261 template <typename gRPCStub>
263 {
264 CloseUnsafeChild();
265
266 StubPtr.reset();
267 }
268}
Implementation of a hardware adapter to communicate text-based commands over TCP sockets.
Defines an exception caused by an operation involving the gRPC library and communication over a TCP s...
static constexpr auto UNIMPLEMENTED_ErrorMsg
Message used for the grpc::StatusCode::UNIMPLEMENTED status code.
Configurator class for gRPCHardwareAdapter.
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...
Parameter class for gRPCHardwareAdapter.
gRPCHardwareAdapterParams(DynExp::ItemIDType ID, const DynExp::DynExpCore &Core)
Constructs the parameters for a gRPCHardwareAdapter instance.
DynExp::NetworkParamsExtension NetworkParams
Bundles several parameters to describe a network connection. Use in parameter classes.
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...
void ConfigureParamsImpl(dispatch_tag< HardwareAdapterParamsBase >) override final
virtual void ConfigureParamsImpl(dispatch_tag< gRPCHardwareAdapterParams >)
This template class provides basic functionality to design hardware adapters for instruments which co...
void EnsureReadyStateChild() override final
Ensures that this Object instance is ready by possibly starting its worker thread or by opening conne...
void OpenUnsafe()
Establishes the connection to a gRPC server creating a new gRPC stub, which is stored in StubPtr.
void CheckError(const grpc::Status Result, const std::source_location Location=std::source_location::current()) const
Checks whether Result denotes an error state. If this is the case, a respective gRPCException is cons...
virtual void ResetImpl(dispatch_tag< gRPCHardwareAdapter >)
void ResetImpl(dispatch_tag< HardwareAdapterBase >) override final
gRPCStub gRPCStubType
gRPCStub gRPC stub class which is used to transfer data.
bool IsConnectedChild() const noexcept override final
Determines the connection status of the hardware interface.
gRPCStub::Stub & GetStubUnsafe() const
Getter for the gRPC stub.
void CloseUnsafe()
Closes the connection to a gRPC server. StubPtr becomes nullptr.
bool IsOpenedUnsafe() const noexcept
Checks whether the gRPCHardwareAdapter is connected to a server.
std::unique_ptr< typename gRPCStub::Stub > StubPtr
Pointer to the gRPC stub.
virtual std::string GetName() const override
Returns the name of this Object type.
bool IsReadyChild() const override final
Returns wheter this Object instance is ready (e.g. it is running or connected to a hardware device) a...
virtual void CloseUnsafeChild()
Override to add additional termination steps. Gets executed before the gRPC connection is disconnecte...
virtual std::string GetCategory() const override
Returns the category of this Object type.
static constexpr auto Category() noexcept
Every derived class has to redefine this function.
gRPCHardwareAdapter(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType &&Params)
static constexpr auto Name() noexcept
Every derived class has to redefine this function.
DynExp's core class acts as the interface between the user interface and DynExp's internal data like ...
Definition DynExpCore.h:127
Defines the base class for a hardware adapter object. Hardware adapters describe interfaces/connectio...
Configurator class for HardwareAdapterBase.
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
DynExp exceptions are derived from this class. It contains basic information about the cause of the e...
Definition Exception.h:51
Exception(std::string Description, const ErrorType Type=ErrorType::Error, const int ErrorCode=-1, const std::source_location Location=std::source_location::current()) noexcept
Constructs an exception. Constructor is noexcept, although std::runtime_error() might throw std::bad_...
Definition Exception.cpp:8
Thrown when some operation or feature is temporarily or permanently not available.
Definition Exception.h:286
DynExp's hardware namespace contains the implementation of DynExp hardware adapters which extend DynE...
DynExp's main namespace contains the implementation of DynExp including classes to manage resources (...
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.
void ForwardException(std::exception_ptr e)
Wraps the exception passed to the function in a ForwardedException and throws the ForwardedException....
Definition Exception.cpp:30
Accumulates include statements to provide a precompiled header.