1 #ifndef NETSCHEDULE_SERVER__HPP
2 #define NETSCHEDULE_SERVER__HPP
3 
4 /*  $Id: ns_server.hpp 573688 2018-10-31 14:21:21Z satskyse $
5  * ===========================================================================
6  *
7  *                            PUBLIC DOMAIN NOTICE
8  *               National Center for Biotechnology Information
9  *
10  *  This software/database is a "United States Government Work" under the
11  *  terms of the United States Copyright Act.  It was written as part of
12  *  the author's official duties as a United States Government employee and
13  *  thus cannot be copyrighted.  This software/database is freely available
14  *  to the public for use. The National Library of Medicine and the U.S.
15  *  Government have not placed any restriction on its use or reproduction.
16  *
17  *  Although all reasonable efforts have been taken to ensure the accuracy
18  *  and reliability of the software and data, the NLM and the U.S.
19  *  Government do not and cannot warrant the performance or results that
20  *  may be obtained by using this software or data. The NLM and the U.S.
21  *  Government disclaim all warranties, express or implied, including
22  *  warranties of performance, merchantability or fitness for any particular
23  *  purpose.
24  *
25  *  Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors:  Anatoliy Kuznetsov, Victor Joukov
30  *
31  * File Description: NetScheduler threaded server
32  *
33  */
34 
35 #include <string>
36 #include <connect/server.hpp>
37 #include <connect/services/json_over_uttp.hpp>
38 
39 #include "ns_server_misc.hpp"
40 #include "ns_server_params.hpp"
41 #include "ns_queue.hpp"
42 #include "ns_alert.hpp"
43 #include "ns_start_ids.hpp"
44 
45 BEGIN_NCBI_SCOPE
46 
47 class CQueueDataBase;
48 
49 const unsigned int   kSubmitCounterInitialValue = 1000000000;
50 
51 
52 //////////////////////////////////////////////////////////////////////////
53 /// NetScheduler threaded server
54 ///
55 /// @internal
56 class CNetScheduleServer : public CServer
57 {
58 public:
59     CNetScheduleServer(const string &  dbpath, bool  diskless);
60     virtual ~CNetScheduleServer();
61 
IsLog() const62     const bool & IsLog() const
63     { return m_LogFlag; }
IsLogBatchEachJob() const64     const bool & IsLogBatchEachJob() const
65     { return m_LogBatchEachJobFlag; }
IsLogNotificationThread() const66     const bool & IsLogNotificationThread() const
67     { return m_LogNotificationThreadFlag; }
IsLogCleaningThread() const68     const bool & IsLogCleaningThread() const
69     { return m_LogCleaningThreadFlag; }
IsLogExecutionWatcherThread() const70     const bool & IsLogExecutionWatcherThread() const
71     { return m_LogExecutionWatcherThreadFlag; }
IsLogStatisticsThread() const72     const bool & IsLogStatisticsThread() const
73     { return m_LogStatisticsThreadFlag; }
GetStatInterval() const74     const unsigned int & GetStatInterval() const
75     { return m_StatInterval; }
GetJobCountersInterval() const76     const unsigned int & GetJobCountersInterval() const
77     { return m_JobCountersInterval; }
GetRefuseSubmits() const78     bool GetRefuseSubmits() const
79     { return m_RefuseSubmits; }
SetRefuseSubmits(bool val)80     void SetRefuseSubmits(bool  val)
81     { m_RefuseSubmits = val; }
GetInactivityTimeout(void) const82     unsigned GetInactivityTimeout(void) const
83     { return m_InactivityTimeout; }
GetHost()84     string & GetHost()
85     { return m_Host; }
GetPort() const86     unsigned GetPort() const
87     { return m_Port; }
GetDeleteBatchSize(void) const88     unsigned GetDeleteBatchSize(void) const
89     { return m_DeleteBatchSize; }
GetUseHostname(void) const90     bool GetUseHostname(void) const
91     { return m_UseHostname; }
GetDiskless(void) const92     bool GetDiskless(void) const
93     { return m_Diskless; }
GetMarkdelBatchSize(void) const94     unsigned GetMarkdelBatchSize(void) const
95     { return m_MarkdelBatchSize; }
GetScanBatchSize(void) const96     unsigned GetScanBatchSize(void) const
97     { return m_ScanBatchSize; }
GetPurgeTimeout(void) const98     double GetPurgeTimeout(void) const
99     { return m_PurgeTimeout; }
GetHostNetAddr() const100     unsigned GetHostNetAddr() const
101     { return m_HostNetAddr; }
GetStartTime(void) const102     const CTime & GetStartTime(void) const
103     { return m_StartTime; }
GetBackgroundHost()104     CBackgroundHost & GetBackgroundHost()
105     { return m_BackgroundHost; }
GetMaxClientData(void) const106     unsigned int GetMaxClientData(void) const
107     { return m_MaxClientData; }
GetNodeID(void) const108     string GetNodeID(void) const
109     { return m_NodeID; }
GetSessionID(void) const110     string GetSessionID(void) const
111     { return m_SessionID; }
GetAffRegistrySettings(void) const112     SNSRegistryParameters GetAffRegistrySettings(void) const
113     { return m_AffRegistrySettings; }
GetGroupRegistrySettings(void) const114     SNSRegistryParameters GetGroupRegistrySettings(void) const
115     { return m_GroupRegistrySettings; }
GetScopeRegistrySettings(void) const116     SNSRegistryParameters GetScopeRegistrySettings(void) const
117     { return m_ScopeRegistrySettings; }
IsDrainShutdown(void) const118     bool IsDrainShutdown(void) const
119     { return m_CurrentSubmitsCounter.Get() < kSubmitCounterInitialValue; }
WasDBDrained(void) const120     bool WasDBDrained(void) const
121     { return m_DBDrained; }
SetDrainShutdown(void)122     void SetDrainShutdown(void)
123     { m_CurrentSubmitsCounter.Add(-1*static_cast<int>
124                                             (kSubmitCounterInitialValue)); }
GetCurrentSubmitsCounter(void)125     unsigned int  GetCurrentSubmitsCounter(void)
126     { return m_CurrentSubmitsCounter.Get(); }
IncrementCurrentSubmitsCounter(void)127     unsigned int  IncrementCurrentSubmitsCounter(void)
128     { return m_CurrentSubmitsCounter.Add(1); }
DecrementCurrentSubmitsCounter(void)129     unsigned int  DecrementCurrentSubmitsCounter(void)
130     { return m_CurrentSubmitsCounter.Add(-1); }
GetAdminHosts(void) const131     const CNetScheduleAccessList & GetAdminHosts(void) const
132     { return m_AdminHosts; }
GetCompoundIDPool(void) const133     CCompoundIDPool GetCompoundIDPool(void) const
134     { return m_CompoundIDPool; }
SetJobsStartID(const string & qname,unsigned int value)135     void SetJobsStartID(const string &  qname, unsigned int  value)
136     { m_StartIDs.Set(qname, value); }
GetJobsStartID(const string & qname)137     unsigned int GetJobsStartID(const string &  qname)
138     { return m_StartIDs.Get(qname); }
LoadJobsStartIDs(void)139     void LoadJobsStartIDs(void)
140     { m_StartIDs.Load(); }
SerializeJobsStartIDs(void)141     void SerializeJobsStartIDs(void)
142     { m_StartIDs.Serialize(); }
143 
144 
145     void AddDefaultListener(IServer_ConnectionFactory* factory);
146     CJsonNode SetNSParameters(const SNS_Parameters &  new_params,
147                               bool                    limited);
148     CJsonNode ReadServicesConfig(const CNcbiRegistry &  reg);
149 
150     virtual bool ShutdownRequested(void);
151     void SetShutdownFlag(int signum = 0, bool  db_was_drained = false);
152     void SetQueueDB(CQueueDataBase* qdb);
153 
154     // Queue handling
155     unsigned int  Configure(const IRegistry &  reg,
156                             CJsonNode &        diff);
157     unsigned CountActiveJobs() const;
158     CRef<CQueue> OpenQueue(const string &  name);
159     void CreateDynamicQueue(const CNSClientId &  client,
160                             const string &  qname,
161                             const string &  qclass,
162                             const string &  description);
163     void DeleteDynamicQueue(const CNSClientId &  client,
164                             const string &  qname);
165     SQueueParameters  QueueInfo(const string &  qname) const;
166     string  GetQueueNames(const string &  sep) const;
167     string PrintTransitionCounters(void);
168     string PrintJobsStat(const CNSClientId &  client);
169     string GetQueueClassesInfo(void) const;
170     string GetQueueClassesConfig(void) const;
171     string GetQueueInfo(void) const;
172     string GetQueueConfig(void) const;
173     string GetLinkedSectionConfig(void) const;
174     string GetServiceToQueueSectionConfig(void) const;
175     string ResolveService(const string &  service) const;
176     void GetServices(map<string, string> &  services) const;
177 
178     bool AdminHostValid(unsigned host) const;
179     bool IsAdminClientName(const string &  name) const;
180     bool ShouldPerfLogTransitions(const string &  queue_name,
181                                   const string &  class_name) const;
182 
183     void InitNodeID(const string &  db_path);
184 
185     static CNetScheduleServer*  GetInstance(void);
186     string GetAdminClientNames(void) const;
187     string GetStateTransitionPerfLogQueues(void) const;
188     string GetStateTransitionPerfLogClasses(void) const;
189 
190     string GetAlerts(void) const;
191     string SerializeAlerts(void) const;
192     enum EAlertAckResult AcknowledgeAlert(const string &  id,
193                                           const string &  user);
194     enum EAlertAckResult AcknowledgeAlert(EAlertType  alert_type,
195                                           const string &  user);
196     void RegisterAlert(EAlertType  alert_type,
197                        const string &  message);
198     void SetRAMConfigFileChecksum(const string &  checksum);
GetRAMConfigFileChecksum(void) const199     string GetRAMConfigFileChecksum(void) const
200     { return m_RAMConfigFileChecksum; }
201     void SetDiskConfigFileChecksum(const string &  checksum);
GetDiskConfigFileChecksum(void) const202     string GetDiskConfigFileChecksum(void) const
203     { return m_DiskConfigFileChecksum; }
SetAnybodyCanReconfigure(bool val)204     void SetAnybodyCanReconfigure(bool  val)
205     { m_AnybodyCanReconfigure = val; }
AnybodyCanReconfigure(void) const206     bool AnybodyCanReconfigure(void) const
207     { return m_AnybodyCanReconfigure; }
GetReserveDumpSpace(void) const208     unsigned int GetReserveDumpSpace(void) const
209     { return m_ReserveDumpSpace; }
210     map<string, int> GetPauseQueues(void) const;
211     vector<string> GetRefuseSubmitQueues(void) const;
212     string GetDataPath(void) const;
213 
214 protected:
215     virtual void Exit();
216 
217 private:
218     // API for background threads
219     CNetScheduleBackgroundHost      m_BackgroundHost;
220     // Host name where server runs
221     string                          m_Host;
222     unsigned                        m_Port;
223     unsigned                        m_HostNetAddr;
224     mutable bool                    m_Shutdown;
225     int                             m_SigNum;  // Shutdown signal number
226     // Time to wait for the client (seconds)
227     unsigned int                    m_InactivityTimeout;
228     CQueueDataBase *                m_QueueDB;
229     CTime                           m_StartTime;
230 
231     // Log related flags
232     bool                            m_LogFlag;
233     bool                            m_LogBatchEachJobFlag;
234     bool                            m_LogNotificationThreadFlag;
235     bool                            m_LogCleaningThreadFlag;
236     bool                            m_LogExecutionWatcherThreadFlag;
237     bool                            m_LogStatisticsThreadFlag;
238 
239     bool                            m_RefuseSubmits;
240     bool                            m_UseHostname;
241 
242     bool                            m_Diskless;
243 
244     // Support for shutdown with drain
245     CAtomicCounter                  m_CurrentSubmitsCounter;
246     bool                            m_DBDrained;
247 
248 
249     // Purge() related parameters
250     unsigned int                    m_DeleteBatchSize;  // Max # for erasing
251     unsigned int                    m_MarkdelBatchSize; // Max # for marking
252     unsigned int                    m_ScanBatchSize;    // Max # of scanned
253     double                          m_PurgeTimeout;     // Time between purges
254     unsigned int                    m_StatInterval;
255     unsigned int                    m_JobCountersInterval;
256 
257     unsigned int                    m_MaxClientData;
258 
259     string                          m_NodeID;           // From the ini file
260     string                          m_SessionID;        // Generated
261 
262     SNSRegistryParameters           m_AffRegistrySettings;
263     SNSRegistryParameters           m_GroupRegistrySettings;
264     SNSRegistryParameters           m_ScopeRegistrySettings;
265 
266     // List of admin stations
267     CNetScheduleAccessList          m_AdminHosts;
268 
269     static CNetScheduleServer *     sm_netschedule_server;
270 
271     mutable CRWLock                 m_AdminClientsLock;
272     vector<string>                  m_AdminClientNames;
273 
274     mutable CRWLock                 m_STPerfLogQCLock;
275     vector<string>                  m_StateTransitionPerfLogQueues;
276     vector<string>                  m_StateTransitionPerfLogClasses;
277 
278     CNSAlerts                       m_Alerts;
279 
280     mutable CFastMutex              m_ServicesLock;
281     map< string, string >           m_Services;
282 
283     CNSStartIDs                     m_StartIDs;
284 
285     CCompoundIDPool                 m_CompoundIDPool;
286 
287     string                          m_RAMConfigFileChecksum;
288     string                          m_DiskConfigFileChecksum;
289 
290     bool                            m_AnybodyCanReconfigure;
291 
292     unsigned int                    m_ReserveDumpSpace;
293 
294 private:
295     string x_GenerateGUID(void) const;
296     CJsonNode x_SetAdminClientNames(const string &  client_names);
297     CJsonNode x_SetFromList(const string &  from, vector<string> &  to,
298                             CRWLock &  lock);
299 
300 #if defined(_DEBUG) && !defined(NDEBUG)
301 private:
302     SErrorEmulatorParameter     debug_fd_count;
303     SErrorEmulatorParameter     debug_mem_count;
304     SErrorEmulatorParameter     debug_write_delay;
305     SErrorEmulatorParameter     debug_conn_drop_before_write;
306     SErrorEmulatorParameter     debug_conn_drop_after_write;
307     SErrorEmulatorParameter     debug_reply_with_garbage;
308     string                      debug_garbage;
309 
310 public:
GetDebugFDCount(void) const311     SErrorEmulatorParameter  GetDebugFDCount(void) const
312     { return debug_fd_count; }
GetDebugMemCount(void) const313     SErrorEmulatorParameter  GetDebugMemCount(void) const
314     { return debug_mem_count; }
GetDebugWriteDelay(void) const315     SErrorEmulatorParameter  GetDebugWriteDelay(void) const
316     { return debug_write_delay; }
GetDebugConnDropBeforeWrite(void) const317     SErrorEmulatorParameter  GetDebugConnDropBeforeWrite(void) const
318     { return debug_conn_drop_before_write; }
GetDebugConnDropAfterWrite(void) const319     SErrorEmulatorParameter  GetDebugConnDropAfterWrite(void) const
320     { return debug_conn_drop_after_write; }
GetDebugReplyWithGarbage(void) const321     SErrorEmulatorParameter  GetDebugReplyWithGarbage(void) const
322     { return debug_reply_with_garbage; }
GetDebugGarbage(void) const323     string                   GetDebugGarbage(void) const
324     { return debug_garbage; }
325 #endif
326 };
327 
328 
329 END_NCBI_SCOPE
330 
331 #endif
332 
333