HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG_Service.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * COMMENTS:
7  */
8 
9 #ifndef __PDG_SERVICE_H__
10 #define __PDG_SERVICE_H__
11 
12 #include "PDG_API.h"
13 #include "PDG_RegisteredType.h"
14 #include "PDG_ServiceTypes.h"
15 #include "PDG_WorkItemTypes.h"
16 
17 #include <PDGT/PDGT_ValueArgs.h>
18 
19 #include <UT/UT_Array.h>
20 #include <UT/UT_Lock.h>
21 #include <UT/UT_Options.h>
22 #include <UT/UT_StringArray.h>
23 #include <UT/UT_StringHolder.h>
24 #include <UT/UT_UniquePtr.h>
25 
26 class PDG_GraphContext;
27 class PDG_Scheduler;
28 class PDG_ServiceClient;
29 class UT_Thread;
30 class UT_WorkBuffer;
31 
32 namespace PDGN
33 {
34  class PDGN_Message;
35  class PDGN_PollingClientNNG;
36 }
37 
38 /*
39  * Represents a registered service object, tracks the list of active clients
40  * for the service, and keeps track of various settings like the service
41  * pool size, MQ connection information, and service state.
42  */
44 {
45 public:
46  /// Constructs a new service instance with a default pool size of 1, and
47  /// no connection information.
49  const PDG_BaseType* type,
50  const PDGT_ValueArgs& extra_args,
51  bool internal_service);
52 
53  ~PDG_Service() override;
54 
55  /// Sets/gets the unique name for the service. The name of the service is
56  /// unique to the PDG_ServiceManager that created it.
58  { myName = name; }
59  const UT_StringHolder& name() const
60  { return myName; }
61 
62  /// Returns true if the service is internal to PDG. Internal services
63  /// cannot be directly managed by users.
64  bool isInternal() const
65  { return myIsInternal; }
66 
67  /// Sets/gets the persistent flag, which determines whether a service
68  /// should be persisted to the pdgservice JSON configuration file. A
69  /// service that isn't persistent will be lost when the Houdini session
70  /// is closed.
71  void setPersistent(bool persistent)
72  { myIsPersistent = persistent; }
73  bool isPersistent() const
74  { return myIsPersistent; }
75 
76  /// Sets/gets the autostart flag, which indicates that the service will
77  /// start automatically when work items need to use it.
78  void setAutoStart(bool auto_start)
79  { myIsAutoStart = auto_start; }
80  bool isAutoStart() const
81  { return myIsAutoStart; }
82 
83  /// Sets/gets the custom data dictionary on the service.
84  void setData(const UT_OptionsHolder& new_data)
85  { myData = new_data; }
87  { return myData; }
88 
89  /// Sets/gets the MQ url that the service should use to relay messages
90  /// between service clients and the PDG graph
91  void setMqUrl(const UT_StringHolder& url)
92  { myMqUrl = url; }
93  const UT_StringHolder& mqUrl() const
94  { return myMqUrl; }
95 
96  /// Sets/gets the log level for the MQ process that relays messages
97  /// between clients and the PDG graph
98  void setMqLogLevel(int log_level)
99  { myMqLogLevel = log_level; }
100  int mqLogLevel() const
101  { return myMqLogLevel; }
102 
103  /// Sets/gets the port used by the MQ relay.
104  void setMqPort(int mq_port)
105  { myMqPort = mq_port; }
106  int mqPort() const
107  { return myMqPort; }
108 
109  /// Sets/gets the directory that service clients should write their log
110  /// files to.
111  void setClientLogDir(const UT_StringHolder& log_dir)
112  { myClientLogDir = log_dir; }
114  { return myClientLogDir; }
115 
116  /// Sets/gets the directory that the MQ relay writes its logs to.
117  void setMqLogDir(const UT_StringHolder& log_dir)
118  { myMqLogDir = log_dir; }
119  const UT_StringHolder& mqLogDir() const
120  { return myMqLogDir; }
121 
122  /// Sets how the service itself should log output
124  { myClientLogType = log_type; }
126  { return myClientLogType; }
127 
128  /// Sets/gets the names for the environment variables to be set in
129  /// this job's environment. This only applies if the service does not
130  /// have a scheduler.
131  void setEnvVarNames(const UT_StringArray& env_var_names)
132  { myEnvVarNames = env_var_names; }
134  { return myEnvVarNames; }
135 
136  /// Sets/gets the values for the environment variables to be set in
137  /// this job's environment. This only applies if the service does not
138  /// have a scheduler.
139  void setEnvVarValues(const UT_StringArray& env_var_values)
140  { myEnvVarValues = env_var_values; }
142  { return myEnvVarValues; }
143 
144  /// Sets/gets the extra args array for the service
146  { myExtraArguments = args; }
148  { return myExtraArguments; }
149 
150  /// Returns the command line string for the service
151  const UT_StringHolder& command() const;
152 
153  /// Returns the script file path for the service
154  const UT_StringHolder& script() const;
155 
156  /// Sets the service scheduler type
157  void setServiceSchedulerType(
159 
160  /// Sets the scheduler type name
161  void setSchedulerTypeName(
162  const UT_StringHolder& type_name);
163 
164  /// For scheduler services, sets the name of the scheduler and graph
165  /// that created the service.
166  void setScheduler(
167  const UT_StringHolder& name,
168  const UT_StringHolder& context_name);
169 
170  /// Clears the scheduler information associated with a scheduler
171  /// service
172  void clearScheduler();
173 
174  /// Returns the type of scheduler service in use
177  { return myServiceSchedulerType; }
178 
179  /// Returns the type name of the scheduler associated with the service,
180  /// if it's a scheduler service
182  { return mySchedulerTypeName; }
183 
184  /// Returns the name of the scheduler associated with the service, if
185  /// it's a scheduler service
187  { return mySchedulerName; }
188 
189  /// Returns the name of the graph that owns the scheduler that created
190  /// the service, if it's a scheduler service
192  { return mySchedulerContextName; }
193 
194  /// Sets/gets the service owner type -- either a session service or a
195  /// scheduler service
197  { myServiceOwner = owner; }
199  { return myServiceOwner; }
200 
201  /// Sets/gets the current state of the service
203  { myState = state; }
205  { return myState; }
206 
207  /// Sets/gets the pool size for the service, which determines the number
208  /// of concurrent client processes that service executes
209  void setPoolSize(int pool_size)
210  { myPoolSize = pool_size; }
211  int poolSize() const
212  { return myPoolSize; }
213 
214  /// Sets/gets the connection port for the service itself
215  void setPort(int port)
216  { myPort = port; }
217  int port() const
218  { return myPort; }
219 
220  /// Sets the service connection timeout in milliseconds
221  void setConnectionTimeout(int ms)
222  { myConnectionTimeout = ms; }
223  int connectionTimeout() const
224  { return myConnectionTimeout; }
225 
226  /// Sets the memory limit and reset type for the service
228  PDG_ServiceResetType memory_reset_type)
229  {
230  myMemoryResetType = memory_reset_type;
231  }
233  exint memory_limit)
234  {
235  myMemoryLimit = memory_limit;
236  }
238  { return myMemoryResetType; }
240  { return myMemoryLimit; }
241 
242  /// Returns true if the service is start or is already running
243  bool isStartingOrRunning() const;
244 
245  /// Returns true if the service is stopping, or has already stopped
246  bool isStoppingOrStopped() const;
247 
248  /// Returns true if the service is using the specified scheduler
249  bool isRunningOnScheduler(
250  const PDG_Scheduler* scheduler);
251 
252  /// Returns the scheduler that the service is running on, if any
253  PDG_Scheduler* runningScheduler() const;
254 
255 
256  /// Queries the list of all active service client names
257  UT_StringArray clientNames() const;
258 
259  /// Queries the name of a particular service client, using its client
260  /// number
261  UT_StringHolder clientName(int client_num) const;
262 
263  /// Returns the service client info for a particular client
264  PDG_ServiceClient* client(const UT_StringHolder& name);
265 
266  /// Adds a pending service client, which can be waiting on using
267  /// waitForClients
268  PDG_ServiceClient* addPendingClient(
269  const UT_StringHolder& server_address,
270  int server_port,
271  int client_num);
272 
273  /// Stats a service pool. If background is true the service processes are
274  /// start asynchronously, and control immediately returns after calling
275  /// this function. It's up to the caller to ensure that the service has
276  /// started before using it. Returns either success, failure, or already-
277  /// running.
278  PDG_ServiceStartResult startService(
279  UT_WorkBuffer& errors,
280  const PDG_GraphContext* context,
281  bool background);
282 
283  /// Resets a specific service client, or all clients if empty string is
284  /// passed in as the client_name
285  bool resetClient(
286  UT_WorkBuffer& errors,
287  const UT_StringHolder& client_name =
289 
290  /// Restarts a service client. If client_name is empty string all
291  /// clients are restarted.
292  bool restartClient(
293  UT_WorkBuffer& errors,
294  const UT_StringHolder& client_name);
295 
296  /// Stops a service client and kills the process associated with it.
297  /// The client can be started again at a later point using restartClient.
298  /// If client_name is empty string all clients are stoppped.
299  bool stopClient(
300  UT_WorkBuffer& errors,
301  const UT_StringHolder& client_name);
302 
303  /// Immediately kills the process associated with a service client.
304  /// The client can be started again at a later point using restartClient.
305  /// If client_name is empty string all clients are stoppped.
306  bool killClient(
307  UT_WorkBuffer& errors,
308  const UT_StringHolder& client_name);
309 
310  /// Stops the service if it's running, and returns a boolean to indiate
311  /// the status.
312  bool stopService(
313  UT_WorkBuffer& errors,
314  bool ignore_stopped);
315 
316  /// Kills the service if it's running, and returns a boolean to indiate
317  /// the status.
318  bool killService(
319  UT_WorkBuffer& errors,
320  bool ignore_stopped);
321 
322  /// Resumes any service clients that were stopped previously and returns
323  /// a boolean to indicate the status. Has no effect on clients that are
324  /// already running.
325  bool resumeService(
326  UT_WorkBuffer& errors,
327  const PDG_GraphContext* context);
328 
329 
330  /// Cleans up the clients in the service. This method is public so that
331  /// schedulers can call it on services they manage.
332  bool cleanupService(
333  UT_WorkBuffer& errors,
334  bool stop_mq_server,
335  bool wait_for_clients);
336 
337  /// Submits a work item to a service client asynchronously, and returns
338  /// the pending message handle for the job.
339  PDGN::PDGN_Message* executeWorkItem(
340  UT_WorkBuffer& errors,
341  const UT_StringHolder& client_name,
342  const PDG_WorkItem* work_item,
343  bool as_native,
344  bool apply_wedges);
345 
346  /// Submits a work item to a service client asychronously, and returns
347  /// the pending messae handle for the job. This variant of the method
348  /// allows the caller to supply a custom script that will run instead of
349  /// the standard job script or script data associated with the work item.
350  PDGN::PDGN_Message* executeWorkItem(
351  UT_WorkBuffer& errors,
352  const UT_StringHolder& client_name,
353  const PDG_WorkItem* work_item,
354  const UT_WorkBuffer& script_buffer,
355  bool as_native,
356  bool apply_wedges);
357 
358  /// Starts a background thread that polls the ready listener until all
359  /// service clients have connected. If a graph context is passed in, the
360  /// polling client will cancel automatically if the cook associated with
361  /// the context is canceled
362  void startPollingClient(
363  const PDG_GraphContext* context);
364 
365  /// Stops the ready listener. If wait is true then the method will block
366  /// until pending clients have started, otherwise it will forcible stop
367  /// the polling client
368  void stopPollingClient(bool wait);
369 
370  /// Returns the name of the polling client, if one exists
371  const UT_StringHolder& pollingClientName() const;
372 
373  /// Returns true if the service has an active polling client
374  bool hasPollingClient() const
375  { return (myPollingClient != nullptr); }
376 
377  // Returns a pointer to the polling client, or nullptr if none exists.
378  PDGN::PDGN_PollingClientNNG*
380  { return myPollingClient.get(); }
381 
382  /// Returns the command for the service client with the specified client
383  /// number, as a string.
384  UT_StringHolder getCommand(
385  const char* server_address,
386  int server_port,
387  int client_num) const;
388 
389  /// Returns the command for the service client with the specified client
390  /// number, as an array of arguments
391  void getCommand(
392  UT_StringArray& command_tokens,
393  const char* server_address,
394  int server_port,
395  int client_num) const;
396 
397  /// Pings the specified client, and returns true if the client was
398  /// reachable
399  bool ping(int client_num, UT_WorkBuffer& errors) const;
400 
401  /// Pings the first connected client, and returns true if the client was
402  /// reachable
403  bool ping(UT_WorkBuffer& errors) const;
404 
405 private:
406  friend class PDG_ServiceScheduler;
407  friend class PDG_ServiceManager;
408 
409  enum ClientCleanupType
410  {
411  eClientCleanupNone,
412  eClientCleanupWait,
413  eClientCleanupKill
414  };
415 
416  static void* runSpawnSessionService(void* param);
417  static void* runPollingThread(void* param);
418  static void* runCleanupThread(void* param);
419 
420  bool getClientNameFromMessage(
421  PDGN::PDGN_Message* msg,
422  UT_StringHolder& client_name);
423 
424  bool startSessionService(
425  UT_WorkBuffer& errors,
426  const PDG_GraphContext* context,
427  bool background);
428  bool spawnSessionServiceClients(
429  UT_WorkBuffer& errors,
430  const PDG_GraphContext* context);
431 
432  void pollClients();
433  void waitClients();
434 
435  bool stopService(
436  UT_WorkBuffer& errors,
437  ClientCleanupType cleanup_type,
438  bool ignore_stopped);
439  bool stopClient(
440  UT_WorkBuffer& errors,
441  int client_index,
442  bool restart);
443  bool killClient(
444  UT_WorkBuffer& errors,
445  int client_index,
446  bool restart);
447  bool resetClient(
448  UT_WorkBuffer& errors,
449  PDG_ServiceClient* client);
450  bool cleanupClients(
451  UT_WorkBuffer& errors,
452  ClientCleanupType cleanup_type,
453  bool stop_mq_server);
454 
456  acquireClient(
457  UT_StringHolder& client_name,
458  PDG_WorkItemID item_lock);
459  bool releaseClient(
460  UT_WorkBuffer& errors,
461  const UT_StringHolder& client_name,
462  PDG_ServiceResetWhen reset_when,
463  PDG_ServiceResetType reset_type,
464  int64 memory_usage);
465  bool unlockClient(
466  PDG_WorkItemID item_lock,
467  PDG_ServiceResetType reset_type,
468  UT_WorkBuffer& errors);
469  bool killClientProcess(
470  UT_WorkBuffer& errors,
471  PDG_ServiceClient* client);
472  bool restartClientProcess(
473  UT_WorkBuffer& errors,
474  int client_index);
475 
476  PDG_Scheduler* configureServiceScheduler(
477  const PDG_GraphContext* context,
478  UT_WorkBuffer& errors);
479  PDG_Scheduler* serviceScheduler(
480  UT_WorkBuffer& errors) const;
481 
482 private:
483  static constexpr int theMaxConcurrentStartup = 24;
484  static constexpr int theSleepTime = 10;
485  static constexpr int theMQSleepTime = 100;
486  static const UT_StringHolder
487  theDataVersion;
488 
489  using PollingClientPtr = UT_UniquePtr<PDGN::PDGN_PollingClientNNG>;
490 
491 private:
492  PDG_ServiceClientArray myPendingClients;
493  PDG_ServiceClientArray myActiveClients;
494  PDG_ServiceClientArray myCleanupClients;
495  PDG_WorkItemIDSet myActiveLocks;
496 
497  UT_StringHolder myName;
498  UT_StringHolder mySchedulerTypeName;
499  UT_StringHolder mySchedulerName;
500  UT_StringHolder mySchedulerContextName;
501 
502  UT_StringHolder myRunningSchedulerName;
503  UT_StringHolder myRunningSchedulerContextName;
504 
505  UT_StringHolder myMqUrl;
506  UT_StringHolder myMqLogDir;
507  UT_StringHolder myClientLogDir;
508 
509  UT_StringArray myEnvVarNames;
510  UT_StringArray myEnvVarValues;
511  UT_StringArray myExtraArguments;
512 
513  PollingClientPtr myPollingClient;
514  const PDG_GraphContext* myPollingContext;
515  UT_Thread* myPollingThread;
516  UT_Thread* myStartThread;
517  UT_Thread* myCleanupThread;
518 
519  UT_OptionsHolder myData;
520 
521  exint myMemoryLimit;
522 
523  pid_t myMqPid;
524 
525  int myConnectionTimeout;
526  int myMqLogLevel;
527  int myMqPort;
528  int myPoolSize;
529  int myPort;
530 
531  PDG_ServiceOwner myServiceOwner;
533  myServiceSchedulerType;
534  PDG_ServiceState myState;
535  PDG_ServiceLogType myClientLogType;
536 
537  PDG_ServiceResetType myMemoryResetType;
538 
539  bool myIsAutoStart;
540  bool myIsInternal;
541  bool myIsPersistent;
542 
543  UT_Lock myServiceLock;
544  mutable UT_Lock myClientLock;
545 };
546 
547 #endif
exint PDG_WorkItemID
Type defs for unique work item IDs.
void setState(PDG_ServiceState state)
Sets/gets the current state of the service.
Definition: PDG_Service.h:202
PDG_ServiceResetType
const UT_StringArray & envVarValues() const
Definition: PDG_Service.h:141
void setOwner(PDG_ServiceOwner owner)
Definition: PDG_Service.h:196
void setExtraArguments(const UT_StringArray &args)
Sets/gets the extra args array for the service.
Definition: PDG_Service.h:145
int mqPort() const
Definition: PDG_Service.h:106
void setName(const UT_StringHolder &name)
Definition: PDG_Service.h:57
#define PDG_API
Definition: PDG_API.h:23
int64 exint
Definition: SYS_Types.h:125
void setMqUrl(const UT_StringHolder &url)
Definition: PDG_Service.h:91
void setMemoryLimit(exint memory_limit)
Definition: PDG_Service.h:232
void setMqLogLevel(int log_level)
Definition: PDG_Service.h:98
void setEnvVarNames(const UT_StringArray &env_var_names)
Definition: PDG_Service.h:131
PDG_ServiceAcquireResult
Enumeration of return codes when acquiring a service client.
bool isPersistent() const
Definition: PDG_Service.h:73
void setAutoStart(bool auto_start)
Definition: PDG_Service.h:78
const UT_StringHolder & schedulerName() const
Definition: PDG_Service.h:186
const UT_StringHolder & mqLogDir() const
Definition: PDG_Service.h:119
void setClientLogType(PDG_ServiceLogType log_type)
Sets how the service itself should log output.
Definition: PDG_Service.h:123
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
int poolSize() const
Definition: PDG_Service.h:211
void setConnectionTimeout(int ms)
Sets the service connection timeout in milliseconds.
Definition: PDG_Service.h:221
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
void setClientLogDir(const UT_StringHolder &log_dir)
Definition: PDG_Service.h:111
const UT_StringArray & envVarNames() const
Definition: PDG_Service.h:133
bool isAutoStart() const
Definition: PDG_Service.h:80
void setEnvVarValues(const UT_StringArray &env_var_values)
Definition: PDG_Service.h:139
static const UT_StringHolder theEmptyString
constexpr std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size(){return subtype_count< typename std::tuple_element< I, T >::type >::value+tuple_type_size< T, I+1 >);}template< typename T > struct type_count< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size< T, 0 >)};};template< typename T > struct subtype_count{static constexpr int value{is_mutable_container< T >::value?expected_max_vector_size:type_count< T >::value};};template< typename T, typename Enable=void > struct type_count_min{static const int value{0};};template< typename T >struct type_count_min< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_tuple_like< T >::value &&!is_wrapper< T >::value &&!is_complex< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{type_count< T >::value};};template< typename T > struct type_count_min< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr int value{1};};template< typename T >struct type_count_min< T, typename std::enable_if< is_wrapper< T >::value &&!is_complex< T >::value &&!is_tuple_like< T >::value >::type >{static constexpr int value{subtype_count_min< typename T::value_type >::value};};template< typename T, std::size_t I >constexpr typename std::enable_if< I==type_count_base< T >::value, int >::type tuple_type_size_min(){return 0;}template< typename T, std::size_t I > constexpr typename std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size_min(){return subtype_count_min< typename std::tuple_element< I, T >::type >::value+tuple_type_size_min< T, I+1 >);}template< typename T > struct type_count_min< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size_min< T, 0 >)};};template< typename T > struct subtype_count_min{static constexpr int value{is_mutable_container< T >::value?((type_count< T >::value< expected_max_vector_size)?type_count< T >::value:0):type_count_min< T >::value};};template< typename T, typename Enable=void > struct expected_count{static const int value{0};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_wrapper< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{1};};template< typename T > struct expected_count< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr int value{expected_max_vector_size};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&is_wrapper< T >::value >::type >{static constexpr int value{expected_count< typename T::value_type >::value};};enum class object_category:int{char_value=1, integral_value=2, unsigned_integral=4, enumeration=6, boolean_value=8, floating_point=10, number_constructible=12, double_constructible=14, integer_constructible=16, string_assignable=23, string_constructible=24, other=45, wrapper_value=50, complex_number=60, tuple_value=70, container_value=80,};template< typename T, typename Enable=void > struct classify_object{static constexpr object_category value{object_category::other};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&!std::is_same< T, char >::value &&std::is_signed< T >::value &&!is_bool< T >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::integral_value};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value &&!std::is_same< T, char >::value &&!is_bool< T >::value >::type >{static constexpr object_category value{object_category::unsigned_integral};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_same< T, char >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::char_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_bool< T >::value >::type >{static constexpr object_category value{object_category::boolean_value};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_floating_point< T >::value >::type >{static constexpr object_category value{object_category::floating_point};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&std::is_assignable< T &, std::string >::value >::type >{static constexpr object_category value{object_category::string_assignable};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&(type_count< T >::value==1)&&std::is_constructible< T, std::string >::value >::type >{static constexpr object_category value{object_category::string_constructible};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::enumeration};};template< typename T > struct classify_object< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr object_category value{object_category::complex_number};};template< typename T > struct uncommon_type{using type=typename std::conditional<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&!std::is_constructible< T, std::string >::value &&!is_complex< T >::value &&!is_mutable_container< T >::value &&!std::is_enum< T >::value, std::true_type, std::false_type >::type;static constexpr bool value=type::value;};template< typename T >struct classify_object< T, typename std::enable_if<(!is_mutable_container< T >::value &&is_wrapper< T >::value &&!is_tuple_like< T >::value &&uncommon_type< T >::value)>::type >{static constexpr object_category value{object_category::wrapper_value};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::number_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&!is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::integer_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::double_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< is_tuple_like< T >::value &&((type_count< T >::value >=2 &&!is_wrapper< T >::value)||(uncommon_type< T >::value &&!is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value)||(uncommon_type< T >::value &&type_count< T >::value >=2))>::type >{static constexpr object_category value{object_category::tuple_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr object_category value{object_category::container_value};};template< typename T, enable_if_t< classify_object< T >::value==object_category::char_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"CHAR";}template< typename T, enable_if_t< classify_object< T >::value==object_category::integral_value||classify_object< T >::value==object_category::integer_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"INT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::unsigned_integral, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"UINT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::floating_point||classify_object< T >::value==object_category::number_constructible||classify_object< T >::value==object_category::double_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"FLOAT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::enumeration, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"ENUM";}template< typename T, enable_if_t< classify_object< T >::value==object_category::boolean_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"BOOLEAN";}template< typename T, enable_if_t< classify_object< T >::value==object_category::complex_number, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"COMPLEX";}template< typename T, enable_if_t< classify_object< T >::value >=object_category::string_assignable &&classify_object< T >::value<=object_category::other, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"TEXT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::container_value||classify_object< T >::value==object_category::wrapper_value, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value==1, detail::enabler >=detail::dummy >inline std::string type_name(){return type_name< typename std::decay< typename std::tuple_element< 0, T >::type >::type >);}template< typename T, std::size_t I >inline typename std::enable_if< I==type_count_base< T >::value, std::string >::type tuple_name(){return std::string{};}template< typename T, std::size_t I >inline typename std::enable_if<(I< type_count_base< T >::value), std::string >::type tuple_name(){auto str=std::string{type_name< typename std::decay< typename std::tuple_element< I, T >::type >::type >)}+ ','+tuple_name< T, I+1 >);if(str.back()== ',') str.pop_back();return str;}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler > > std::string type_name()
Recursively generate the tuple type name.
Definition: CLI11.h:1729
int mqLogLevel() const
Definition: PDG_Service.h:100
PDG_ServiceResetWhen
When service clients should be reset.
PDG_ServiceSchedulerType serviceSchedulerType() const
Returns the type of scheduler service in use.
Definition: PDG_Service.h:176
long long int64
Definition: SYS_Types.h:116
void setMqPort(int mq_port)
Sets/gets the port used by the MQ relay.
Definition: PDG_Service.h:104
PDG_ServiceResetType memoryResetType() const
Definition: PDG_Service.h:237
GLuint const GLchar * name
Definition: glcorearb.h:786
bool isInternal() const
Definition: PDG_Service.h:64
void setData(const UT_OptionsHolder &new_data)
Sets/gets the custom data dictionary on the service.
Definition: PDG_Service.h:84
const UT_OptionsHolder & data()
Definition: PDG_Service.h:86
void setMemoryResetType(PDG_ServiceResetType memory_reset_type)
Sets the memory limit and reset type for the service.
Definition: PDG_Service.h:227
PDGN::PDGN_PollingClientNNG * getPollingClient() const
Definition: PDG_Service.h:379
*tasks wait()
PDG_ServiceLogType
Enumeration of service log types.
GLenum GLfloat param
Definition: glcorearb.h:104
void setPersistent(bool persistent)
Definition: PDG_Service.h:71
PDG_ServiceOwner owner() const
Definition: PDG_Service.h:198
bool stopClient(UT_WorkBuffer &errors, const UT_StringHolder &service_name, const UT_StringHolder &client_name=UT_StringHolder::theEmptyString)
const UT_StringArray & extraArguments() const
Definition: PDG_Service.h:147
const UT_StringHolder & schedulerTypeName() const
Definition: PDG_Service.h:181
const UT_StringHolder & mqUrl() const
Definition: PDG_Service.h:93
const UT_StringHolder & name() const
Definition: PDG_Service.h:59
const UT_StringHolder & schedulerContextName() const
Definition: PDG_Service.h:191
bool resetClient(UT_WorkBuffer &errors, const UT_StringHolder &service_name, const UT_StringHolder &client_name=UT_StringHolder::theEmptyString)
const UT_StringHolder & clientLogDir() const
Definition: PDG_Service.h:113
PDG_ServiceOwner
Enumeration of the different types of service owner.
PDG_ServiceStartResult
Enumeration of possible result values from starting a service.
PDG_ServiceState
Enumeration of the different states that a service can be in.
bool stopService(UT_WorkBuffer &errors, const UT_StringHolder &name, bool ignore_stopped)
exint memoryLimit() const
Definition: PDG_Service.h:239
**If you just want to fire and args
Definition: thread.h:618
int connectionTimeout() const
Definition: PDG_Service.h:223
int port() const
Definition: PDG_Service.h:217
PDG_ServiceSchedulerType
bool hasPollingClient() const
Returns true if the service has an active polling client.
Definition: PDG_Service.h:374
void setMqLogDir(const UT_StringHolder &log_dir)
Sets/gets the directory that the MQ relay writes its logs to.
Definition: PDG_Service.h:117
void setPoolSize(int pool_size)
Definition: PDG_Service.h:209
PDG_ServiceState state() const
Definition: PDG_Service.h:204
state
Definition: core.h:2289
PDG_ServiceLogType clientLogType() const
Definition: PDG_Service.h:125
bool killClient(UT_WorkBuffer &errors, const UT_StringHolder &service_name, const UT_StringHolder &client_name=UT_StringHolder::theEmptyString)
void setPort(int port)
Sets/gets the connection port for the service itself.
Definition: PDG_Service.h:215