#ifndef XRD_CLIENT_H
#define XRD_CLIENT_H
/******************************************************************************/
/* */
/* X r d C l i e n t . h h */
/* */
/* Author: Fabrizio Furano (INFN Padova, 2004) */
/* Adapted from TXNetFile (root.cern.ch) originally done by */
/* Alvise Dorigo, Fabrizio Furano */
/* INFN Padova, 2003 */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// A UNIX reference client for xrootd. //
// //
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// //
// //
// Some features: //
// - Automatic server kind recognition (xrootd load balancer, xrootd //
// data server, old rootd) //
// - Fault tolerance for read/write operations (read/write timeouts //
// and retry) //
// - Internal connection timeout (tunable indipendently from the OS //
// one) //
// - Full implementation of the xrootd protocol //
// - handling of redirections from server //
// - Connection multiplexing //
// - Asynchronous operation mode //
// - High performance read caching with read-ahead //
// - Thread safe //
// - Tunable log verbosity level (0 = nothing, 3 = dump read/write //
// buffers too!) //
// - Many parameters configurable. But the default are OK for nearly //
// all the situations. //
// //
//////////////////////////////////////////////////////////////////////////
#include "XProtocol/XProtocol.hh"
#include "XrdClient/XrdClientAbs.hh"
#include "XrdClient/XrdClientConst.hh"
#include "XrdOuc/XrdOucString.hh"
#include "XrdSys/XrdSysSemWait.hh"
#include "XrdVersion.hh"
#include
#include
class XrdClientReadAheadMgr;
class XrdClientThread;
struct XrdClientOpenInfo {
bool inprogress;
bool opened;
kXR_unt16 mode;
kXR_unt16 options;
};
struct XrdClientStatInfo {
int stated;
long long size;
long id;
long flags;
long modtime;
};
struct XrdClientCounters {
int CacheSize;
// This does not take into account the 'suggestions'
// like async read or async readV
// We count only for functions which return data, eventually
// taken from the cache
long long ReadBytes;
long long WrittenBytes;
long long WriteRequests;
long long ReadRequests;
long long ReadMisses;
long long ReadHits;
float ReadMissRate;
long long ReadVRequests; // How many readVs (sync) were requested
long long ReadVSubRequests; // In how many sub-readVs they were split
long long ReadVSubChunks; // How many subchunks in total
long long ReadVBytes; // How many bytes were requested (sync)
long long ReadVAsyncRequests; // How many readVs (async) were requested
long long ReadVAsyncSubRequests; // In how many sub-readVs they were split
long long ReadVAsyncSubChunks; // How many subchunks in total
long long ReadVAsyncBytes; // How many bytes were requested (async)
long long ReadAsyncRequests;
long long ReadAsyncBytes;
};
class XrdClient : public XrdClientAbs {
friend void *FileOpenerThread(void*, XrdClientThread*);
private:
struct XrdClientOpenInfo fOpenPars; // Just a container for the last parameters
// passed to a Open method
// The open request can be in progress. Further requests must be delayed until
// finished.
XrdSysCondVar *fOpenProgCnd;
// Used to open a file in parallel
XrdClientThread *fOpenerTh;
// Used to limit the maximum number of concurrent opens
static XrdSysSemWait fConcOpenSem;
bool fOpenWithRefresh;
XrdSysCondVar *fReadWaitData; // Used to wait for outstanding data
struct XrdClientStatInfo fStatInfo;
long fReadTrimBlockSize;
bool fUseCache;
XrdOucString fInitialUrl;
XrdClientUrlInfo fUrl;
bool TryOpen(kXR_unt16 mode,
kXR_unt16 options,
bool doitparallel);
bool LowOpen(const char *file,
kXR_unt16 mode,
kXR_unt16 options,
char *additionalquery = 0);
void TerminateOpenAttempt();
void WaitForNewAsyncData();
// Real implementation for ReadV
// To call it we need to be aware of the restrictions so the public
// interface should be ReadV()
kXR_int64 ReadVEach(char *buf, kXR_int64 *offsets, int *lens, int &nbuf);
bool IsOpenedForWrite() {
// This supposes that no options means read only
if (!fOpenPars.options) return false;
if (fOpenPars.options & kXR_open_read) return false;
return true;
}
XrdClientReadAheadMgr *fReadAheadMgr;
void PrintCounters();
protected:
XrdClientCounters fCounters;
virtual bool OpenFileWhenRedirected(char *newfhandle,
bool &wasopen);
virtual bool CanRedirOnError() {
// Can redir away on error if no file is opened
// or the file is opened in read mode
if ( !fOpenPars.opened ) return true;
return !IsOpenedForWrite();
}
public:
XrdClient(const char *url, XrdClientCallback *XrdCcb = 0, void *XrdCcbArg = 0);
virtual ~XrdClient();
UnsolRespProcResult ProcessUnsolicitedMsg(XrdClientUnsolMsgSender *sender,
XrdClientMessage *unsolmsg);
bool Close();
// Ask the server to flush its cache
bool Sync();
// Copy the whole file to the local filesystem. Not very efficient.
bool Copy(const char *localpath);
// Returns low level information about the cache
bool GetCacheInfo(
// The actual cache size
int &size,
// The number of bytes submitted since the beginning
long long &bytessubmitted,
// The number of bytes found in the cache (estimate)
long long &byteshit,
// The number of reads which did not find their data
// (estimate)
long long &misscount,
// miss/totalreads ratio (estimate)
float &missrate,
// number of read requests towards the cache
long long &readreqcnt,
// ratio between bytes found / bytes submitted
float &bytesusefulness
);
// Returns client-level information about the activity performed up to now
bool GetCounters( XrdClientCounters *cnt );
// Quickly tells if the file is open
inline bool IsOpen() { return fOpenPars.opened; }
// Tells if the file opening is in progress
bool IsOpen_inprogress();
// Tells if the file is open, waiting for the completion of the parallel open
bool IsOpen_wait();
// Open the file. See the xrootd documentation for mode and options
// If parallel, then the open is done by a separate thread, and
// all the operations are delayed until the open has finished
bool Open(kXR_unt16 mode, kXR_unt16 options, bool doitparallel=true);
// Read a block of data. If no error occurs, it returns all the requested bytes.
int Read(void *buf, long long offset, int len);
// Read multiple blocks of data compressed into a sinle one. It's up
// to the application to do the logistic (having the offset and len to find
// the position of the required buffer given the big one). If no error
// occurs, it returns all the requested bytes.
// NOTE: if buf == 0 then the req will be carried out asynchronously, i.e.
// the result of the request will only populate the internal cache. A subsequent read()
// of that chunk will get the data from the cache
kXR_int64 ReadV(char *buf, long long *offsets, int *lens, int nbuf);
// Submit an asynchronous read request. Its result will only populate the cache
// (if any!!)
XReqErrorType Read_Async(long long offset, int len, bool updatecounters=true);
// Get stat info about the file. Normally it tries to guess the file size variations
// unless force==true
bool Stat(struct XrdClientStatInfo *stinfo, bool force = false);
// On-the-fly enabling/disabling of the cache
bool UseCache(bool u = true);
// To instantly remove all the chunks in the cache
void RemoveAllDataFromCache();
// To remove pieces of data from the cache
void RemoveDataFromCache(long long begin_offs,
long long end_offs,
bool remove_overlapped = false);
// To set at run time the cache/readahead parameters for this instance only
// If a parameter is < 0 then it's left untouched.
// To simply enable/disable the caching, just use UseCache(), not this function
void SetCacheParameters(int CacheSize, int ReadAheadSize, int RmPolicy);
// To enable/disable different read ahead strategies. Defined in XrdClientReadAhead.hh
void SetReadAheadStrategy(int strategy);
// To enable the trimming of the blocks to read. Blocksize will be rounded to a multiple of 512.
// Each read request will have the offset and length aligned with a multiple of blocksize
// This strategy is similar to a read ahead, but not quite. Here we see it as a transformation
// of the stream of the read accesses to request
void SetBlockReadTrimming(int blocksize);
// Truncates the open file at a specified length
bool Truncate(long long len);
// Write data to the file
bool Write(const void *buf, long long offset, int len);
std::vector fExcludedHosts;
};
#endif