Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-08 10:33:34

0001 #ifndef __XRDSSIREQUEST_HH__
0002 #define __XRDSSIREQUEST_HH__
0003 /******************************************************************************/
0004 /*                                                                            */
0005 /*                      X r d S s i R e q u e s t . h h                       */
0006 /*                                                                            */
0007 /* (c) 2013 by the Board of Trustees of the Leland Stanford, Jr., University  */
0008 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
0009 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
0010 /*                                                                            */
0011 /* This file is part of the XRootD software suite.                            */
0012 /*                                                                            */
0013 /* XRootD is free software: you can redistribute it and/or modify it under    */
0014 /* the terms of the GNU Lesser General Public License as published by the     */
0015 /* Free Software Foundation, either version 3 of the License, or (at your     */
0016 /* option) any later version.                                                 */
0017 /*                                                                            */
0018 /* XRootD is distributed in the hope that it will be useful, but WITHOUT      */
0019 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or      */
0020 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public       */
0021 /* License for more details.                                                  */
0022 /*                                                                            */
0023 /* You should have received a copy of the GNU Lesser General Public License   */
0024 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file  */
0025 /* COPYING (GPL license).  If not, see <http://www.gnu.org/licenses/>.        */
0026 /*                                                                            */
0027 /* The copyright holder's institutional names and contributor's names may not */
0028 /* be used to endorse or promote products derived from this software without  */
0029 /* specific prior written permission of the institution or contributor.       */
0030 /******************************************************************************/
0031 
0032 #include <cstdint>
0033 #include <cstdlib>
0034 #include <cstring>
0035 
0036 #include "XrdSsi/XrdSsiAtomics.hh"
0037 #include "XrdSsi/XrdSsiErrInfo.hh"
0038 #include "XrdSsi/XrdSsiRespInfo.hh"
0039 
0040 //-----------------------------------------------------------------------------
0041 //! The XrdSsiRequest class describes a client request and is used to effect a
0042 //! response to the request via a companion object described by XrdSsiResponder.
0043 //! Client-Side: Use this object to encapsulate your request and hand it off
0044 //!              to XrdSsiService::Execute() either use GetResponseData() or
0045 //!              the actual response structure to get the response data once the
0046 //!              ProcessResponse() callback is invoked.
0047 //!
0048 //! Server-side: XrdSsiService::ProcessRequest() is called with this object.
0049 //!              Use the XrdSsiResponder object to post a response.
0050 //!
0051 //! In either case, the client must invoke XrdSsiRequest::Finished() after the
0052 //! client-server exchange is complete in order to revert ownership of this
0053 //! object to the object's creator to allow it to be deleted or reused.
0054 //!
0055 //! This is an abstract class and several methods need to be implemented:
0056 //!
0057 //! Alert()               Optional, allows receiving of server alerts.
0058 //! GetRequest()          Mandatory to supply the buffer holding the request
0059 //!                       along with its length.
0060 //! RelRequestBuffer()    Optional, allows memory optimization.
0061 //! ProcessResponse()     Initial response: Mandatory
0062 //! ProcessResponseData() Data    response: Mandatory only if response data is
0063 //!                                         asynchronously received.
0064 //!
0065 //! All callbacks are invoked with no locks outstanding unless otherwise noted.
0066 //-----------------------------------------------------------------------------
0067 
0068 class XrdSsiResponder;
0069 
0070 class XrdSsiRequest
0071 {
0072 public:
0073 friend class XrdSsiResponder;
0074 friend class XrdSsiRRAgent;
0075 
0076 //-----------------------------------------------------------------------------
0077 //! Indicate that request processing has been finished. This method calls
0078 //! XrdSsiResponder::Finished() on the associated responder object.
0079 //!
0080 //! Note: This method locks the object's recursive mutex.
0081 //!
0082 //! @param  cancel False -> the request/response sequence completed normally.
0083 //!                True  -> the request/response sequence aborted because of an
0084 //!                         error or the client cancelled the request.
0085 //!
0086 //! @return true   Finish accepted. Request object may be reclaimed.
0087 //! @return false  Finish cannot be accepted because this request object is
0088 //!                not bound to a responder. This indicates a logic error.
0089 //-----------------------------------------------------------------------------
0090 
0091         bool    Finished(bool cancel=false);
0092 
0093 //-----------------------------------------------------------------------------
0094 //! Obtain the detached request time to live value. If the value is non-zero,
0095 //! the request is detached. Otherwise, it is an attached request and requires a
0096 //! live TCP connection during it execution.
0097 //!
0098 //! @return The detached time to live value in seconds.
0099 //-----------------------------------------------------------------------------
0100 
0101 inline uint32_t GetDetachTTL() {return detTTL;}
0102 
0103 //-----------------------------------------------------------------------------
0104 //! Obtain the endpoint host name.
0105 //!
0106 //! @return A string containing the endpoint host name. If a null string is
0107 //!         returned, the endpoint has not yet been determined. Generally, the
0108 //!         endpoint is available on the first callback to this object.
0109 //-----------------------------------------------------------------------------
0110 
0111 std::string     GetEndPoint();
0112 
0113 //-----------------------------------------------------------------------------
0114 //! Obtain the metadata associated with a response.
0115 //!
0116 //!
0117 //! Note: This method locks the object's recursive mutex.
0118 //!
0119 //! @param  dlen  holds the length of the metadata after the call.
0120 //!
0121 //! @return =0    No metadata available, dlen has been set to zero.
0122 //! @return !0    Pointer to the buffer holding the metadata, dlen has the length
0123 //-----------------------------------------------------------------------------
0124 
0125 const char     *GetMetadata(int &dlen);
0126 
0127 //-----------------------------------------------------------------------------
0128 //! Obtain the request data sent by a client.
0129 //!
0130 //! This method is duplicated in XrdSsiResponder to allow calling consistency.
0131 //!
0132 //! @param  dlen  holds the length of the request after the call.
0133 //!
0134 //! @return =0    No request data available, dlen has been set to zero.
0135 //! @return !0    Pointer to the buffer holding the request, dlen has the length
0136 //-----------------------------------------------------------------------------
0137 
0138 virtual char   *GetRequest(int &dlen) = 0;
0139 
0140 //-----------------------------------------------------------------------------
0141 //! Get the request ID established at object creation time.
0142 //!
0143 //! @return Pointer to the request ID or nil if there is none.
0144 //-----------------------------------------------------------------------------
0145 
0146 inline
0147 const   char   *GetRequestID() {return reqID;}
0148 
0149 //-----------------------------------------------------------------------------
0150 //! Asynchronously obtain response data. This is a helper method that allows a
0151 //! client to deal with a passive stream response. This method also handles
0152 //! data response, albeit inefficiently by copying the data response. However,
0153 //! this allows for uniform response processing regardless of response type.
0154 //!
0155 //! @param  buff  pointer to the buffer to receive the data. The buffer must
0156 //!               remain valid until ProcessResponseData() is called.
0157 //! @param  blen  the length of the buffer (i.e. maximum that can be returned).
0158 //-----------------------------------------------------------------------------
0159 
0160         void    GetResponseData(char *buff, int  blen);
0161 
0162 //-----------------------------------------------------------------------------
0163 //! Get timeout for initiating the request.
0164 //!
0165 //! @return The timeout value.
0166 //-----------------------------------------------------------------------------
0167 
0168         uint16_t GetTimeOut() {return tOut;}
0169 
0170 //-----------------------------------------------------------------------------
0171 //! Notify request that a response is ready to be processed. This method must
0172 //! be supplied by the request object's implementation.
0173 //!
0174 //! @param  eInfo Error information. You can check if an error occurred using
0175 //!               eInfo.hasError() or eInfo.isOK().
0176 //! @param  rInfo Raw response information.
0177 //!
0178 //! @return true  Response processed.
0179 //! @return false Response could not be processed, the request is not active.
0180 //-----------------------------------------------------------------------------
0181 
0182 virtual bool    ProcessResponse(const XrdSsiErrInfo  &eInfo,
0183                                 const XrdSsiRespInfo &rInfo)=0;
0184 
0185 //-----------------------------------------------------------------------------
0186 //! Handle incoming async stream data or error. This method is called by a
0187 //! stream object after a successful GetResponseData() or an asynchronous
0188 //! stream SetBuff() call.
0189 //!
0190 //! @param  eInfo Error information. You can check if an error occurred using
0191 //!               eInfo.hasError() or eInfo.isOK().
0192 //! @param  buff  Pointer to the buffer given to XrdSsiStream::SetBuff().
0193 //! @param  blen  The number of bytes in buff or an error indication if blen < 0.
0194 //! @param  last  true  This is the last stream segment, no more data remains.
0195 //!               false More data may remain in the stream.
0196 //-----------------------------------------------------------------------------
0197 
0198 virtual void ProcessResponseData(const XrdSsiErrInfo  &eInfo, char *buff,
0199                                  int blen, bool last) {}
0200 
0201 //-----------------------------------------------------------------------------
0202 //! Release the request buffer of the request bound to this object. This method
0203 //! duplicates the protected method RelRequestBuffer() and exists here for
0204 //! calling safety and consistency relative to the responder.
0205 //-----------------------------------------------------------------------------
0206 
0207         void   ReleaseRequestBuffer();
0208 
0209 //-----------------------------------------------------------------------------
0210 //! Constructor
0211 //!
0212 //! @param reqid   Pointer to a request ID that can be used to group requests.
0213 //!                See ProcessResponseData() and RestartDataReponse(). If reqid
0214 //!                is nil then held responses are placed in the global queue.
0215 //!                The pointer must be valid for the life of this object.
0216 //!
0217 //! @param tmo     The request initiation timeout value 0 equals default).
0218 //-----------------------------------------------------------------------------
0219 
0220                 XrdSsiRequest(const char *reqid=0, uint16_t tmo=0);
0221 
0222 protected:
0223 
0224 //-----------------------------------------------------------------------------
0225 //! @brief Send or receive a server generated alert.
0226 //!
0227 //! The Alert() method is used server-side to send one or more alerts before a
0228 //! response is posted (alerts afterwards are ignored). To avoid race conditions,
0229 //! server-side alerts should be sent via the Responder's Alert() method.
0230 //! Clients must implement this method in order to receive alerts.
0231 //!
0232 //! @param  aMsg   Reference to the message object containing the alert message.
0233 //!                Non-positive alert lengths cause the alert call to be
0234 //!                ignored. You should call the message RecycleMsg() method
0235 //!                once you have consumed the message to release its resources.
0236 //-----------------------------------------------------------------------------
0237 
0238 virtual void    Alert(XrdSsiRespInfoMsg &aMsg) {aMsg.RecycleMsg(false);}
0239 
0240 //-----------------------------------------------------------------------------
0241 //! Release the request buffer. Use this method to optimize storage use; this
0242 //! is especially relevant for long-running requests. If the request buffer
0243 //! has been consumed and is no longer needed, early return of the buffer will
0244 //! minimize memory usage. This method is also invoked via XrdSsiResponder.
0245 //!
0246 //!
0247 //! Note: This method is called with the object's recursive mutex locked when
0248 //!       it is invoked via XrdSsiResponder's ReleaseRequestBuffer().
0249 //-----------------------------------------------------------------------------
0250 
0251 virtual void    RelRequestBuffer() {}
0252 
0253 //-----------------------------------------------------------------------------
0254 //! @brief Set the detached request time to live value.
0255 //!
0256 //! By default, requests are executed in the foreground (i.e. during its
0257 //! execution, if the TCP connection drops, the request is automatically
0258 //! cancelled. When a non-zero time to live is set, the request is executed in
0259 //! the background (i.e. detached) and no persistent TCP connection is required.
0260 //! You must use the XrdSsiService::Attach() method to foreground such a
0261 //! request within the number of seconds specified for dttl or the request is
0262 //! automatically cancelled. The value must be set before passing the request
0263 //! to XrdSsiService::ProcessRequest(). Once the request is started, a request
0264 //! handle is returned which can be passed to XrdSsiService::Attach().
0265 //!
0266 //! @param  dttl The detach time to live value.
0267 //-----------------------------------------------------------------------------
0268 
0269 inline void     SetDetachTTL(uint32_t dttl) {detTTL = dttl;}
0270 
0271 //-----------------------------------------------------------------------------
0272 //! Set request retry notification. If a non-default value is desired, it must
0273 //! be set prior to calling XrdSsiService::ProcessRequest(). This is a one-time
0274 //! request and retry mode is turned off in the request object afterwards.
0275 //!
0276 //! @param onoff   True to turn retry on and false to turn it off.
0277 //-----------------------------------------------------------------------------
0278 
0279        void     SetRetry(bool onoff);
0280 
0281 //-----------------------------------------------------------------------------
0282 //! Set timeout for initiating the request. If a non-default value is desired,
0283 //! it must be set prior to calling XrdSsiService::ProcessRequest().
0284 //!
0285 //! @param tmo     The timeout value.
0286 //-----------------------------------------------------------------------------
0287 
0288        void     SetTimeOut(uint16_t tmo) {tOut = tmo;}
0289 
0290 //-----------------------------------------------------------------------------
0291 //! Destructor. This object can only be deleted by the object creator. Once the
0292 //! object is passed to XrdSsiService::ProcessRequest() it may only be deleted
0293 //! after Finished() is called to allow the service to reclaim any resources
0294 //! allocated for the request object.
0295 //-----------------------------------------------------------------------------
0296 
0297 virtual        ~XrdSsiRequest() {}
0298 
0299 private:
0300 virtual void     BindDone() {}
0301         void     CleanUp();
0302         bool     CopyData(char *buff, int blen);
0303 virtual void     Dispose() {}
0304 
0305 const char      *reqID;
0306 XrdSsiMutex     *rrMutex;
0307 XrdSsiResponder *theRespond; // Set via XrdSsiResponder::BindRequest()
0308 XrdSsiRespInfo   Resp;       // Set via XrdSsiResponder::SetResponse()
0309 XrdSsiErrInfo    errInfo;
0310 long long        rsvd1;
0311 const char      *epNode;
0312 uint32_t         detTTL;
0313 uint16_t         tOut;
0314 bool             onClient;
0315 char             flags;
0316 static const int isaRetry = 1;
0317 };
0318 #endif