NCBI C++ ToolKit
request_ctx.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef CORELIB___REQUEST_CTX__HPP
2 #define CORELIB___REQUEST_CTX__HPP
3 
4 /* $Id: request_ctx.hpp 99291 2023-03-07 16:40:29Z ivanov $
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: Aleksey Grichenko, Denis Vakatov
30  *
31  * File Description:
32  * Request context for diagnostic framework.
33  *
34  */
35 
36 /// @file request_ctx.hpp
37 ///
38 /// Defines CRequestContext class for NCBI C++ diagnostic API.
39 ///
40 
41 
42 #include <corelib/ncbiobj.hpp>
43 #include <corelib/ncbidiag.hpp>
44 #include <corelib/ncbitime.hpp>
45 #include <corelib/ncbistr.hpp>
47 
48 
49 /** @addtogroup Diagnostics
50  *
51  * @{
52  */
53 
54 
56 
57 
58 // Forward declarations
60 
61 
62 /// Helper class to hold hit id and sub-hit counter which can be shared
63 /// between multiple request contexts.
65 {
66 public:
67  /// Set new hit id, checks its validity
68  explicit CSharedHitId(const string& hit_id)
69  : m_SubHitId(0), m_AppState(GetDiagContext().GetAppState())
70  {
71  x_SetHitId(hit_id);
72  }
73 
74  CSharedHitId(void) : m_SubHitId(0) {}
75  ~CSharedHitId(void) {}
76 
77  bool Empty(void) const { return m_HitId.empty(); }
78 
79  /// Mark this hit id as a shared one and start using shared counter.
80  void SetShared(void) const
81  {
82  if ( IsShared() ) return; // Already shared.
83  m_SharedSubHitId.Reset(new TSharedCounter());
84  m_SharedSubHitId->GetData().Set(m_SubHitId);
85  }
86 
87  /// Check if shared counter is used.
88  bool IsShared(void) const { return !m_SharedSubHitId.Empty(); }
89 
90  /// Get hit id value.
91  const string& GetHitId(void) const { return m_HitId; }
92 
93  /// Set new hit id value. This resets sub-hit counter and makes it non-shared.
94  void SetHitId(const string& hit_id)
95  {
96  m_SharedSubHitId.Reset();
97  m_SubHitId = 0;
98  x_SetHitId(hit_id);
99  m_AppState = GetDiagContext().GetAppState();
100  }
101 
102  typedef unsigned int TSubHitId;
103 
104  /// Get current sub-hit id value.
106  {
107  return IsShared() ? (TSubHitId)m_SharedSubHitId->GetData().Get() : m_SubHitId;
108  }
109 
110  /// Get next sub-hit id value.
112  {
113  return IsShared() ? (TSubHitId)m_SharedSubHitId->GetData().Add(1) : ++m_SubHitId;
114  }
115 
116  /// Check if this hit ID was set at request level.
117  bool IsRequestLevel(void) const
118  {
119  return m_AppState == eDiagAppState_RequestBegin ||
120  m_AppState == eDiagAppState_Request ||
121  m_AppState == eDiagAppState_RequestEnd;
122  }
123 
124 private:
125  /// Set new hit id, checks its validity
126  void x_SetHitId(const string& hit_id);
127 
128 private:
130 
131  string m_HitId;
135 };
136 
137 
138 class CMask;
139 class CMaskFileName;
140 
142 {
143 public:
144  virtual ~IRequestTracer(void) {}
145  virtual void OnRequestStart(CRequestContext& context) = 0;
146  virtual void OnRequestStop(CRequestContext& context) = 0;
147 };
148 
149 
151 {
152 public:
153  virtual ~ITracerSpan(void) {}
154 };
155 
156 
158 {
159 public:
160  /// Request context flags.
162  fResetOnStart = 1, ///< Reset values when printing request-start.
163 
164  fDefault = 0
165  };
166  typedef int TContextFlags;
167 
168  CRequestContext(TContextFlags flags = fDefault);
169  virtual ~CRequestContext(void);
170 
172 
173  /// Get request ID (or zero if not set).
174  TCount GetRequestID(void) const;
175  /// Set request ID.
176  void SetRequestID(TCount rid);
177  /// Check if request ID was assigned a value
178  bool IsSetRequestID(void) const;
179  /// Reset request ID
180  void UnsetRequestID(void);
181  /// Assign the next available request ID to this request.
182  TCount SetRequestID(void);
183 
184  /// Return the next available application-wide request ID.
185  static TCount GetNextRequestID(void);
186 
187  /// Application state
188  EDiagAppState GetAppState(void) const;
189  void SetAppState(EDiagAppState state);
190 
191  /// Client IP/hostname
192  string GetClientIP(void) const;
193  void SetClientIP(const string& client);
194  bool IsSetClientIP(void) const;
195  bool IsSetExplicitClientIP(void) const;
196  void UnsetClientIP(void);
197 
198  /// Session ID
199  string GetSessionID(void) const;
200  void SetSessionID(const string& session);
201  bool IsSetSessionID(void) const;
202  bool IsSetExplicitSessionID(void) const; ///< Does not check default SID
203  void UnsetSessionID(void);
204  /// Create and set new session ID
205  const string& SetSessionID(void);
206  /// Get URL-encoded session ID
207  string GetEncodedSessionID(void) const;
208 
209  /// Hit ID
210  /// Allowed source of the current hit id
211  /// @sa IsSetHitID
213  eHitID_Any = 0, ///< Any hit id - always return true.
214  eHitID_Request = 0x01, ///< Check if per-request hit id is set.
215  eHitID_Default = 0x02, ///< Check if default hit id is set.
216 
217  /// Check if any hit is already available (will not be generated
218  /// on request).
219  eHidID_Existing = eHitID_Default | eHitID_Request
220  };
221 
222  /// Get explicit hit id or the default one (from HTTP_NCBI_PHID etc).
223  /// If none of the above is available, generate a new id for the current
224  /// request.
225  /// If using the default hit id, it is cached in the request context and
226  /// becomes local one.
227  string GetHitID(void) const
228  { return x_GetHitID(CDiagContext::eHitID_Create); }
229  /// Set explicit hit id. The id is reset on request end.
230  void SetHitID(const string& hit);
231  /// Check if there's an explicit hit id or the default one.
232  /// @param src
233  /// Allowed source(s) of hit id.
234  /// @return
235  /// If 'src' is eHitID_Any, always return 'true' because GetHitID
236  /// always returns a non-empty value. For other options return true
237  /// if the selected hit id source is already not empty.
238  bool IsSetHitID(EHitIDSource src = eHitID_Any) const;
239  /// Check if there's an explicit hit id.
240  /// @deprecated Use IsSetHitID(eHitID_Request) instead.
242  bool IsSetExplicitHitID(void) const
243  { return IsSetHitID(eHitID_Request); }
244  /// Reset explicit hit id.
245  void UnsetHitID(void);
246  /// Generate unique hit id, assign it to this request, return
247  /// the hit id value.
248  const string& SetHitID(void);
249  /// Get current hit id appended with auto-incremented sub-hit id.
250  const string& GetNextSubHitID(CTempString prefix = CTempString());
251  /// Get the last generated sub-hit id.
252  const string& GetCurrentSubHitID(CTempString prefix = CTempString());
253 
254  /// Dtab
255  bool IsSetDtab(void) const;
256  const string& GetDtab(void) const;
257  void SetDtab(const string& dtab);
258  void UnsetDtab(void);
259 
260  /// Request exit status
261  int GetRequestStatus(void) const;
262  void SetRequestStatus(int status);
263  void SetRequestStatus(CRequestStatus::ECode code);
264  bool IsSetRequestStatus(void) const;
265  void UnsetRequestStatus(void);
266 
267  /// Request execution timer
268  const CStopWatch& GetRequestTimer(void) const { return m_ReqTimer; }
269  CStopWatch& GetRequestTimer(void) { return m_ReqTimer; }
270 
271  /// Bytes read
272  Int8 GetBytesRd(void) const;
273  void SetBytesRd(Int8 bytes);
274  bool IsSetBytesRd(void) const;
275  void UnsetBytesRd(void);
276 
277  /// Bytes written
278  Int8 GetBytesWr(void) const;
279  void SetBytesWr(Int8 bytes);
280  bool IsSetBytesWr(void) const;
281  void UnsetBytesWr(void);
282 
283  /// Reset all properties to the initial state
284  void Reset(void);
285 
286  /// User-defined request properties
288 
289  /// Add/change property
290  void SetProperty(const string& name, const string& value);
291  /// Get property value or empty string
292  const string& GetProperty(const string& name) const;
293  /// Check if the property has a value (even if it's an empty string).
294  bool IsSetProperty(const string& name) const;
295  /// Remove property from the map
296  void UnsetProperty(const string& name);
297 
298  /// Get all properties (read only)
299  const TProperties& GetProperties(void) const { return m_Properties; }
300  /// Get all properties (non-const)
301  TProperties& GetProperties(void) { return m_Properties; }
302 
303  /// Auto-increment request ID with every posted message
304  void SetAutoIncRequestIDOnPost(bool enable) { m_AutoIncOnPost = enable; }
305  /// Get auto-increment state
306  bool GetAutoIncRequestIDOnPost(void) const { return m_AutoIncOnPost; }
307  /// Set default auto-increment flag used for each default request context.
308  /// Contexts created by users do not check this flag.
309  /// The flag is not MT-protected.
310  static void SetDefaultAutoIncRequestIDOnPost(bool enable);
311  /// Get default auto-increment flag.
312  static bool GetDefaultAutoIncRequestIDOnPost(void);
313 
314  /// Session ID format
316  eSID_Ncbi, ///< Strict NCBI format: (UID:16)_(RqID:4+)SID
317  eSID_Standard, ///< Alpanum, underscore, -.:@, (default)
318  eSID_Other ///< Any other format
319  };
320  /// Session ID error actions
322  eOnBadSID_Allow, ///< Don't validate session id.
323  eOnBadSID_AllowAndReport, ///< Accept but show warning (default).
324  eOnBadSID_Ignore, ///< Ignore bad session id.
325  eOnBadSID_IgnoreAndReport, ///< Ignore and show warning.
326  eOnBadSID_Throw ///< Throw on bad session id.
327  };
328 
329  /// Check if session id fits the allowed format.
330  static bool IsValidSessionID(const string& session_id);
331 
332  /// Get/set session id error action.
333  static EOnBadSessionID GetBadSessionIDAction(void);
334  static void SetBadSessionIDAction(EOnBadSessionID action);
335 
336  /// Get/set allowed session id format.
337  static ESessionIDFormat GetAllowedSessionIDFormat(void);
338  static void SetAllowedSessionIDFormat(ESessionIDFormat fmt);
339 
340  /// Copy current request context to a new one. The method can be used
341  /// to process a single request in several threads which share the same
342  /// information (request id, session id etc.).
343  /// NOTE: The new context is not linked to the parent one. No further
344  /// changes in a context are copied to its clones. It's the developer's
345  /// responsibility to track multiple clones and make sure that they are
346  /// used properly (e.g. status is set by just one thread; only one
347  /// request-stop is printed and no clones continue to log the same request
348  /// after it's stopped).
349  CRef<CRequestContext> Clone(void) const;
350 
351  /// Select the last hit id from the list of ids separated with commas
352  /// and optional spaces.
353  static string SelectLastHitID(const string& hit_ids);
354  /// Select the last session id from the list of ids separated with
355  /// commas and optional spaces, ignore UNK_SESSION value.
356  static string SelectLastSessionID(const string& session_ids);
357 
358  /// Add pass-through value if it matches a pattern from NCBI_CONTEXT_FIELDS.
359  void AddPassThroughProperty(const string& name, const string& value);
360 
361  /// Switch request context to read-only mode. A read-only context
362  /// can be attached to multiple threads. The mode must be disabled
363  /// before making any modifications (e.g. printing request-stop).
364  /// To avoid overhead CRequestContext does not check if there are
365  /// any threads currently using the same context in a different mode.
366  /// Any attempts to modify request context while in read-only mode
367  /// are ignored and reported as an error (once per process).
368  /// Note that some const methods may still need to modify the context
369  /// (e.g. GetHitID() generates a new hit id if it's not yet assigned).
370  /// To prevent the above error from being logged, the method should be
371  /// called at least once before switching to read-only mode.
372  void SetReadOnly(bool read_only) { m_IsReadOnly = read_only; }
373  /// Get current read-only flag.
374  bool GetReadOnly(void) const { return m_IsReadOnly; }
375 
377 
378  /// Return version increased on every context change (hit/subhit id, client ip,
379  /// session id).
380  TVersion GetVersion(void) const { return m_Version; }
381 
382  /// Set request tracer to be called on context events (start/stop etc.).
383  /// @sa IRequestTracer
384  void SetRequestTracer(const shared_ptr<IRequestTracer>& tracer) { m_Tracer = tracer; }
385 
386  void SetTracerSpan(const shared_ptr<ITracerSpan>& span) { m_TracerSpan = span; }
387  shared_ptr<ITracerSpan> GetTracerSpan(void) { return m_TracerSpan; }
388 
389 private:
390  // Prohibit copying
393 
394  // Start/Stop methods must be visible in CDiagContext
395  friend class CDiagContext;
396 
397  // Mark the current request as running.
398  // Reset request status, bytes rd/wr, restart timer.
399  void StartRequest(void);
400 
401  // Mark the current request as finished.
402  // Reset all values (call Reset()).
403  void StopRequest(void);
404 
405  // Check if the request is running.
406  bool IsRunning(void) const { return m_IsRunning; }
407 
408  enum EProperty {
409  eProp_RequestID = 1 << 0,
410  eProp_ClientIP = 1 << 1,
411  eProp_SessionID = 1 << 2,
412  eProp_HitID = 1 << 3,
413  eProp_ReqStatus = 1 << 4,
414  eProp_BytesRd = 1 << 5,
415  eProp_BytesWr = 1 << 6,
416  eProp_Dtab = 1 << 7
417  };
418  typedef int TPropSet;
419 
420  bool x_IsSetProp(EProperty prop) const;
421  void x_SetProp(EProperty prop);
422  void x_UnsetProp(EProperty prop);
423 
424  // Log current hit id if not yet logged and if the application state is
425  // 'in request', otherwise postpone logging until StartRequest is executed.
426  // If 'ignore_app_state' is set, log any available hit id anyway.
427  void x_LogHitID(bool ignore_app_state = false) const;
428 
429  void x_SetHitID(const CSharedHitId& hit_id);
430  string x_GetHitID(CDiagContext::EDefaultHitIDFlags flag) const;
431 
432  void x_UpdateSubHitID(bool increment, CTempString prefix);
433 
434  static bool& sx_GetDefaultAutoIncRequestIDOnPost(void);
435 
436  // Methods used by CRequestContext_PassThrough
437  bool x_IsSetPassThroughProp(CTempString name, bool update) const;
438  void x_SetPassThroughProp(CTempString name, CTempString value, bool update) const;
439  const string& x_GetPassThroughProp(CTempString name, bool update) const;
440  void x_ResetPassThroughProp(CTempString name, bool update) const;
441  // Copy std properties from CRequestContext to pass-through data.
442  void x_UpdateStdPassThroughProp(CTempString name) const;
443  // Copy std properties from pass-through data to CRequestContext.
444  void x_UpdateStdContextProp(CTempString name) const;
445 
446  static const CMask& sx_GetContextFieldsMask(void);
447  static string sx_NormalizeContextPropertyName(const string& name);
448 
449  // Load environment values matching NCBI_CONTEXT_FIELDS.
450  void x_LoadEnvContextProperties(void);
451 
452  friend class CDiagBuffer;
453  bool x_LogHitIDOnError(void) const;
454 
455  bool x_CanModify(void) const;
456 
457  // Bumps context version.
458  void x_Modify(void);
459 
461  fLoggedOnRequest = 1, // Logged on creation or request start
462  fLoggedOnError = 2 // Logged on ERR_POST when applog messages are disabled
463  };
464 
467  string m_ClientIP;
470  string m_Dtab;
471  mutable int m_HitIDLoggedFlag;
482 
483  // For saving/checking owner TID.
485  // TID of the thread currently using this context or -1.
489 
490  // Name/value map for properties to be passed between requests.
491  // @sa CRequestContext_PassThrough
493 
494  // Access to passable properties.
497 
498  shared_ptr<IRequestTracer> m_Tracer;
499  shared_ptr<ITracerSpan> m_TracerSpan;
500 
501  // Patterns from NCBI_CONTEXT_FIELDS variable.
502  static unique_ptr<CMaskFileName> sm_ContextFields;
503 
504  // Context values loaded from the global environment.
505  static unique_ptr<TPassThroughProperties> sm_EnvContextProperties;
506 
508 };
509 
510 
511 /// Request context properties passed between tasks.
513 {
514 public:
515  /// Get CRequestContext_PassThrough for the current request context.
517 
518  /// Get CRequestContext_PassThrough for the specific request context.
520 
521  /// Supported serialization/deserialization formats.
522  enum EFormat {
523  eFormat_UrlEncoded ///< name=value pairs URL-encoded and separated with '&'
524  };
525 
526  /// Check if the property is set.
527  bool IsSet(CTempString name) const;
528 
529  /// Set or update property value.
530  void Set(CTempString name, CTempString value);
531 
532  /// Get current property value or empty string if it's not set;
533  const string& Get(CTempString name) const;
534 
535  /// Reset property.
536  void Reset(CTempString name);
537 
538  /// Serialize current values using the specified format.
539  string Serialize(EFormat format) const;
540 
541  /// Deserialize values using the specified format.
543 
544  /// Enumerate all properties. The callback must have the following signarure:
545  /// bool F(const string& name, const string& value);
546  /// The function should return true to continue enumaration, false to stop.
547  template<class TCallback>
548  void Enumerate(TCallback callback)
549  {
550  m_Context->x_UpdateStdPassThroughProp("");
551  ITERATE(TProperties, it, m_Context->m_PassThroughProperties) {
552  if ( !callback(it->first, it->second) ) break;
553  }
554  }
555 
556 private:
557  string x_SerializeUrlEncoded(void) const;
558  void x_DeserializeUrlEncoded(CTempString data);
559 
561 
563 };
564 
565 
566 /// Take guard of the current CRequestContext, handle app-state, start/stop
567 /// logging and request status in the dtor.
569 {
570 public:
571  enum EFlags {
572  fPrintRequestStart = 1 << 0 ///< Print request-start automatically in the
573  ///< constructor. By default request-start is
574  ///< not printed to allow the caller log request
575  ///< arguments.
576  };
577  typedef int TFlags;
578 
579  /// Initialize guard.
580  /// @param context
581  /// Request context to be used. If null, re-use current context.
582  /// @param flags
583  /// Optional flags, @sa FFlags.
585 
586  /// Destroy guard. If released do nothing. On exception set error status.
587  /// Print request-stop. Restore previous context.
589 
590  /// Set request context status.
591  void SetStatus(int status) { m_RequestContext->SetRequestStatus(status); }
592 
593  /// Set default error status, which will be used if an uncaught exception
594  /// is detected.
595  void SetDefaultErrorStatus(int status);
596 
597  /// Get the guarded request context.
598  CRequestContext& GetRequestContext() const { return *m_RequestContext; }
599 
600  /// Release the guarded context, restore the saved context if any, do not
601  /// perform any other actions (logging, setting status).
602  void Release(void);
603 
604 private:
605  TFlags m_Flags = 0;
606  int m_ErrorStatus = 500;
609  bool m_OriginatesFromThrow = false;
610 };
611 
612 
615 {
616 public:
617  /// Error types that CRequestContext can generate.
618  ///
619  /// These generic error conditions can occur for corelib applications.
620  enum EErrCode {
621  eBadSession, ///< Invalid session id
622  eBadHit ///< Invalid hit id
623  };
624 
625  /// Translate from the error code value to its string representation.
626  virtual const char* GetErrCodeString(void) const override;
627 
628  // Standard exception boilerplate code.
630 };
631 
632 
633 inline
635 {
637 }
638 
639 inline
641 {
642  if (!x_CanModify()) return;
644  m_RequestID = rid;
645  x_Modify();
646 }
647 
648 inline
650 {
651  if (!x_CanModify()) return m_RequestID;
653  return m_RequestID;
654 }
655 
656 inline
658 {
660 }
661 
662 inline
664 {
665  if (!x_CanModify()) return;
667  m_RequestID = 0;
668  x_Modify();
669 }
670 
671 
672 inline
674 {
675  return x_IsSetProp(eProp_ClientIP) ?
677 }
678 
679 inline
681 {
682  return IsSetExplicitClientIP() ||
683  !GetDiagContext().GetDefaultClientIP().empty();
684 }
685 
686 inline
688 {
689  return x_IsSetProp(eProp_ClientIP);
690 }
691 
692 inline
694 {
695  if (!x_CanModify()) return;
697  m_ClientIP.clear();
698  x_Modify();
699 }
700 
701 
702 inline
704 {
705  if ( x_IsSetProp(eProp_SessionID) ) {
707  }
708  string def_sid = GetDiagContext().GetDefaultSessionID();
709  if ( !def_sid.empty() ) return def_sid;
710  return const_cast<CRequestContext*>(this)->SetSessionID();
711 }
712 
713 inline
715 {
716  return x_IsSetProp(eProp_SessionID) ?
719 }
720 
721 inline
723 {
724  return IsSetExplicitSessionID() ||
725  !GetDiagContext().GetDefaultSessionID().empty();
726 }
727 
728 inline
730 {
732 }
733 
734 inline
736 {
737  if (!x_CanModify()) return;
740  x_Modify();
741 }
742 
743 
744 inline
746 {
747  if (src == eHitID_Any) {
748  // Local, default or auto-created hit id is always available.
749  return true;
750  }
751  if ((src & eHitID_Request) && x_IsSetProp(eProp_HitID)) {
752  return m_HitID.IsRequestLevel();
753  }
754  if ((src & eHitID_Default) && GetDiagContext().x_IsSetDefaultHitID()) {
755  return true;
756  }
757  return false;
758 }
759 
760 
761 inline
763 {
764  if (!x_CanModify()) return;
767  x_Modify();
768  m_HitIDLoggedFlag = 0;
769  m_SubHitIDCache.clear();
770 }
771 
772 
773 inline
775 {
776  if (!x_CanModify()) return m_SubHitIDCache;
777  x_UpdateSubHitID(true, prefix);
778  return m_SubHitIDCache;
779 }
780 
781 
782 inline
784 {
785  x_UpdateSubHitID(false, prefix);
786  return m_SubHitIDCache;
787 }
788 
789 
790 inline
792 {
793  return x_IsSetProp(eProp_Dtab);
794 }
795 
796 
797 inline
798 const string& CRequestContext::GetDtab(void) const
799 {
801 }
802 
803 
804 inline
805 void CRequestContext::SetDtab(const string& dtab)
806 {
807  if (!x_CanModify()) return;
809  m_Dtab = dtab;
810 }
811 
812 
813 inline
815 {
816  if (!x_CanModify()) return;
818 }
819 
820 
821 inline
823 {
825 }
826 
827 inline
829 {
830  if (!x_CanModify()) return;
832  m_ReqStatus = status;
833 }
834 
835 inline
837 {
838  if (!x_CanModify()) return;
839  SetRequestStatus((int)code);
840 }
841 
842 inline
844 {
846 }
847 
848 inline
850 {
851  if (!x_CanModify()) return;
853  m_ReqStatus = 0;
854 }
855 
856 
857 inline
859 {
860  return x_IsSetProp(eProp_BytesRd) ? m_BytesRd : 0;
861 }
862 
863 inline
865 {
866  if (!x_CanModify()) return;
868  m_BytesRd = bytes;
869 }
870 
871 inline
873 {
874  return x_IsSetProp(eProp_BytesRd);
875 }
876 
877 inline
879 {
880  if (!x_CanModify()) return;
882  m_BytesRd = 0;
883 }
884 
885 
886 inline
888 {
889  return x_IsSetProp(eProp_BytesWr) ? m_BytesWr : 0;
890 }
891 
892 inline
894 {
895  if (!x_CanModify()) return;
897  m_BytesWr = bytes;
898 }
899 
900 inline
902 {
903  return x_IsSetProp(eProp_BytesWr);
904 }
905 
906 inline
908 {
909  if (!x_CanModify()) return;
911  m_BytesWr = 0;
912 }
913 
914 
915 inline
917 {
918  return m_PropSet & prop ? true : false;
919 }
920 
921 
922 inline
924 {
925  m_PropSet |= prop;
926 }
927 
928 inline
930 {
931  m_PropSet &= ~prop;
932 }
933 
934 
935 inline
937 {
939  return false;
940  }
942  return true;
943 }
944 
945 
946 inline
948 {
949  if ( m_IsReadOnly ) {
950  ERR_POST_ONCE("Attempt to modify a read-only request context.");
951  return false;
952  }
953  return true;
954 }
955 
956 
957 inline
959 {
961 }
962 
963 
964 inline
966 {
967  m_Context.Reset(&GetDiagContext().GetRequestContext());
968 }
969 
970 
971 inline
973  : m_Context(&ctx)
974 {
975 }
976 
977 
978 inline
980 {
981  return m_Context->x_IsSetPassThroughProp(name, true);
982 }
983 
984 
985 inline
987 {
988  m_Context->x_SetPassThroughProp(name, value, true);
989 }
990 
991 
992 inline
994 {
995  return m_Context->x_GetPassThroughProp(name, true);
996 }
997 
998 
999 inline
1001 {
1002  m_Context->x_ResetPassThroughProp(name, true);
1003 }
1004 
1005 
1007 
1008 
1009 #endif /* CORELIB___REQUEST_CTX__HPP */
#define true
Definition: bool.h:35
CAtomicCounter –.
Definition: ncbicntr.hpp:71
Thread local context data stored in TLS.
Definition: ncbidiag.cpp:447
CEncodedString –.
Definition: ncbistr.hpp:4822
EFormat
The formats are checked in the same order as declared here.
CMaskFileName –.
Definition: ncbi_mask.hpp:107
CMask –.
Definition: ncbi_mask.hpp:59
CObjectFor –.
Definition: ncbiobj.hpp:2335
CObject –.
Definition: ncbiobj.hpp:180
CRef –.
Definition: ncbiobj.hpp:618
Take guard of the current CRequestContext, handle app-state, start/stop logging and request status in...
Request context properties passed between tasks.
Helper class to hold hit id and sub-hit counter which can be shared between multiple request contexts...
Definition: request_ctx.hpp:65
CStopWatch –.
Definition: ncbitime.hpp:1938
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
char value[7]
Definition: config.c:431
The NCBI C++ standard methods for dealing with std::string.
static uch flags
CS_CONTEXT * ctx
Definition: t0006.c:12
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
TNCBIAtomicValue TValue
Alias TValue for TNCBIAtomicValue.
Definition: ncbicntr.hpp:73
TValue Add(int delta) THROWS_NONE
Atomically add value (=delta), and return new counter value.
Definition: ncbicntr.hpp:278
EContextFlags
Request context flags.
bool IsSetRequestID(void) const
Check if request ID was assigned a value.
void x_Modify(void)
CStopWatch & GetRequestTimer(void)
CRequestContext & GetRequestContext() const
Get the guarded request context.
TSubHitId GetNextSubHitId(void)
Get next sub-hit id value.
void UnsetRequestStatus(void)
ESessionIDFormat
Session ID format.
bool IsSetBytesRd(void) const
TCount SetRequestID(void)
Assign the next available request ID to this request.
void SetBytesWr(Int8 bytes)
CEncodedString m_SessionID
void SetRequestTracer(const shared_ptr< IRequestTracer > &tracer)
Set request tracer to be called on context events (start/stop etc.).
EErrCode
Error types that CRequestContext can generate.
EDiagAppState m_AppState
int GetRequestStatus(void) const
Request exit status.
#define ERR_POST_ONCE(message)
Error posting only once during program execution.
Definition: ncbidiag.hpp:602
Uint8 TCount
Generic type for counters (posts, requests etc.)
Definition: ncbidiag.hpp:1605
Int8 GetBytesWr(void) const
Bytes written.
CObjectFor< CAtomicCounter > TSharedCounter
string GetEncodedSessionID(void) const
Get url-encoded session id.
Definition: logging.cpp:874
CDiagContext & GetDiagContext(void)
Get diag context instance.
Definition: logging.cpp:818
TProperties & GetProperties(void)
Get all properties (non-const)
bool GetAutoIncRequestIDOnPost(void) const
Get auto-increment state.
TSubHitId GetCurrentSubHitId(void) const
Get current sub-hit id value.
CRef< CRequestContext > m_SavedContext
CSharedHitId(void)
Definition: request_ctx.hpp:74
void SetTracerSpan(const shared_ptr< ITracerSpan > &span)
map< string, string, PNocase > TPassThroughProperties
void x_SetProp(EProperty prop)
void Reset(CTempString name)
Reset property.
TVersion m_Version
void UnsetBytesWr(void)
string GetSessionID(void) const
Session ID.
CAtomicCounter::TValue TVersion
void UnsetClientIP(void)
bool IsSetRequestStatus(void) const
TSubHitId m_SubHitId
bool x_IsSetProp(EProperty prop) const
const string & GetNextSubHitID(CTempString prefix=CTempString())
Get current hit id appended with auto-incremented sub-hit id.
bool IsSetBytesWr(void) const
void SetDtab(const string &dtab)
Int8 GetBytesRd(void) const
Bytes read.
static unique_ptr< TPassThroughProperties > sm_EnvContextProperties
static TCount GetNextRequestID(void)
Return the next available application-wide request ID.
CSharedHitId(const string &hit_id)
Set new hit id, checks its validity.
Definition: request_ctx.hpp:68
const string & Get(CTempString name) const
Get current property value or empty string if it's not set;.
map< string, string > TProperties
User-defined request properties.
CRef< TSharedCounter > m_SharedSubHitId
bool IsSetSessionID(void) const
void SetStatus(int status)
Set request context status.
TCount GetRequestID(void) const
Get request ID (or zero if not set).
CRequestContext_PassThrough(void)
Get CRequestContext_PassThrough for the current request context.
TPropSet m_PropSet
string GetClientIP(void) const
Client IP/hostname.
virtual ~IRequestTracer(void)
void x_LogHitID(void) const
Definition: ncbidiag.cpp:2968
void x_SetPassThroughProp(CTempString name, CTempString value, bool update) const
void SetHitId(const string &hit_id)
Set new hit id value. This resets sub-hit counter and makes it non-shared.
Definition: request_ctx.hpp:94
static string GetDefaultClientIP(void)
Get default client ip.
Definition: ncbidiag.cpp:2932
void Enumerate(TCallback callback)
Enumerate all properties.
void SetAutoIncRequestIDOnPost(bool enable)
Auto-increment request ID with every posted message.
void SetRequestStatus(int status)
EDiagAppState m_AppState
bool IsSetHitID(EHitIDSource src=eHitID_Any) const
Check if there's an explicit hit id or the default one.
bool IsSet(CTempString name) const
Check if the property is set.
void UnsetRequestID(void)
Reset request ID.
CStopWatch m_ReqTimer
const string & GetDtab(void) const
static CAtomicCounter sm_VersionCounter
bool x_IsSetPassThroughProp(CTempString name, bool update) const
bool x_LogHitIDOnError(void) const
EHitIDSource
Hit ID Allowed source of the current hit id.
const CStopWatch & GetRequestTimer(void) const
Request execution timer.
EFormat
Supported serialization/deserialization formats.
CRef< CRequestContext > m_Context
static unique_ptr< CMaskFileName > sm_ContextFields
bool GetReadOnly(void) const
Get current read-only flag.
void UnsetDtab(void)
bool IsSetDtab(void) const
Dtab.
void UnsetSessionID(void)
bool IsSetExplicitClientIP(void) const
string m_SubHitIDCache
const string & x_GetPassThroughProp(CTempString name, bool update) const
void x_ResetPassThroughProp(CTempString name, bool update) const
bool IsRunning(void) const
void Set(CTempString name, CTempString value)
Set or update property value.
const string & SetSessionID(void)
Create and set new session ID.
CRequestContext & operator=(const CRequestContext &)
bool IsSetExplicitHitID(void) const
Check if there's an explicit hit id.
void SetBytesRd(Int8 bytes)
EDiagAppState
Application execution states shown in the std prefix.
Definition: ncbidiag.hpp:789
bool IsSetClientIP(void) const
shared_ptr< ITracerSpan > m_TracerSpan
shared_ptr< ITracerSpan > GetTracerSpan(void)
void UnsetBytesRd(void)
TProperties m_Properties
bool IsShared(void) const
Check if shared counter is used.
Definition: request_ctx.hpp:88
SDiagMessage::TCount TCount
EOnBadSessionID
Session ID error actions.
EDiagAppState GetAppState(void) const
Return application state for the current thread if it's set.
Definition: ncbidiag.cpp:2802
bool Empty(void) const
Definition: request_ctx.hpp:77
void UnsetHitID(void)
Reset explicit hit id.
unsigned int TSubHitId
string GetHitID(void) const
Get explicit hit id or the default one (from HTTP_NCBI_PHID etc).
virtual void OnRequestStart(CRequestContext &context)=0
const TProperties & GetProperties(void) const
Get all properties (read only)
~CSharedHitId(void)
Definition: request_ctx.hpp:75
virtual void OnRequestStop(CRequestContext &context)=0
NCBI_EXCEPTION_DEFAULT(CRequestContextException, CException)
bool IsSetExplicitSessionID(void) const
Does not check default SID.
TPassThroughProperties m_PassThroughProperties
TVersion GetVersion(void) const
Return version increased on every context change (hit/subhit id, client ip, session id).
virtual ~ITracerSpan(void)
void SetShared(void) const
Mark this hit id as a shared one and start using shared counter.
Definition: request_ctx.hpp:80
CSharedHitId m_HitID
void SetReadOnly(bool read_only)
Switch request context to read-only mode.
CRequestContext::TPassThroughProperties TProperties
TContextFlags m_Flags
shared_ptr< IRequestTracer > m_Tracer
const string & GetHitId(void) const
Get hit id value.
Definition: request_ctx.hpp:91
string GetDefaultSessionID(void) const
Get default session id.
Definition: logging.cpp:868
CRequestContext(const CRequestContext &)
bool IsRequestLevel(void) const
Check if this hit ID was set at request level.
void x_UnsetProp(EProperty prop)
const string & GetCurrentSubHitID(CTempString prefix=CTempString())
Get the last generated sub-hit id.
void x_UpdateSubHitID(bool increment, CTempString prefix)
CRef< CRequestContext > m_RequestContext
string GetEncodedSessionID(void) const
Get URL-encoded session ID.
bool x_CanModify(void) const
@ eSID_Ncbi
Strict NCBI format: (UID:16)_(RqID:4+)SID.
@ eSID_Standard
Alpanum, underscore, -.:@, (default)
@ eBadSession
Invalid session id.
@ eHitID_Request
Check if per-request hit id is set.
@ eHitID_Default
Check if default hit id is set.
@ eHitID_Any
Any hit id - always return true.
@ eDiagAppState_RequestEnd
RE.
Definition: ncbidiag.hpp:796
@ eDiagAppState_RequestBegin
RB.
Definition: ncbidiag.hpp:794
@ eDiagAppState_Request
R.
Definition: ncbidiag.hpp:795
@ eOnBadSID_Allow
Don't validate session id.
@ eOnBadSID_IgnoreAndReport
Ignore and show warning.
@ eOnBadSID_AllowAndReport
Accept but show warning (default).
@ eOnBadSID_Ignore
Ignore bad session id.
#define EXCEPTION_VIRTUAL_BASE
Do not use virtual base classes in exception declaration at all, because in this case derived class s...
Definition: ncbiexpt.hpp:1388
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
#define NCBI_DEPRECATED
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
const string & GetEncodedString(void) const
Get encoded string.
Definition: ncbistr.hpp:4837
const string & GetOriginalString(void) const
Get the original unencoded string.
Definition: ncbistr.hpp:4835
void SetString(const CTempString s, NStr::EUrlEncode flag=NStr::eUrlEnc_SkipMarkChars)
Set new original string.
Definition: ncbistr.cpp:7303
#define NCBI_XNCBI_EXPORT
Definition: ncbi_export.h:1283
const TYPE & Get(const CNamedParameterList *param)
Defines NCBI C++ diagnostic APIs, classes, and macros.
Portable reference counted smart and weak pointers using CWeakRef, CRef, CObject and CObjectEx.
Defines: CTimeFormat - storage class for time format.
static Format format
Definition: njn_ioutil.cpp:53
static const char * prefix[]
Definition: pcregrep.c:405
Defines CRequestStatus class for NCBI C++ diagnostic API.
static CNamedPipeClient * client
Definition: inftrees.h:24
void Serialize(CNcbiOstream &, const CRawScoreVector< Key, Score > &)
Generics These throw an exception; we must implement serialization for each type.
void Deserialize(CNcbiIstream &istr, CRawScoreVector< Key, Score > &)
Modified on Sat Dec 02 09:22:25 2023 by modify_doxy.py rev. 669887