xrootd
XrdClOperations.hh
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // Copyright (c) 2011-2017 by European Organization for Nuclear Research (CERN)
3 // Author: Krzysztof Jamrog <krzysztof.piotr.jamrog@cern.ch>,
4 // Michal Simon <michal.simon@cern.ch>
5 //------------------------------------------------------------------------------
6 // This file is part of the XRootD software suite.
7 //
8 // XRootD is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Lesser General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 //
13 // XRootD is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public License
19 // along with XRootD. If not, see <http://www.gnu.org/licenses/>.
20 //
21 // In applying this licence, CERN does not waive the privileges and immunities
22 // granted to it by virtue of its status as an Intergovernmental Organization
23 // or submit itself to any jurisdiction.
24 //------------------------------------------------------------------------------
25 
26 #ifndef __XRD_CL_OPERATIONS_HH__
27 #define __XRD_CL_OPERATIONS_HH__
28 
29 #include <memory>
30 #include <stdexcept>
31 #include <sstream>
32 #include <tuple>
33 #include <future>
36 #include "XrdClArg.hh"
37 #include "XrdSys/XrdSysPthread.hh"
38 
39 namespace XrdCl
40 {
41 
42  template<bool HasHndl> class Operation;
43 
44  class Pipeline;
45 
46 
47  //----------------------------------------------------------------------------
49  //----------------------------------------------------------------------------
50  typedef std::function<Operation<true>*(const XRootDStatus&)> rcvry_func;
51 
52  //----------------------------------------------------------------------------
55  //----------------------------------------------------------------------------
57  {
58  template<bool> friend class Operation;
59 
60  public:
61 
62  //------------------------------------------------------------------------
67  //------------------------------------------------------------------------
69  rcvry_func &&recovery );
70 
71  //------------------------------------------------------------------------
73  //------------------------------------------------------------------------
75  {
76  }
77 
78  //------------------------------------------------------------------------
80  //------------------------------------------------------------------------
82  HostList *hostList );
83 
84  //------------------------------------------------------------------------
86  //------------------------------------------------------------------------
87  void HandleResponse( XRootDStatus *status, AnyObject *response );
88 
89  //------------------------------------------------------------------------
91  //------------------------------------------------------------------------
93  {
94  }
95 
96  //------------------------------------------------------------------------
100  //------------------------------------------------------------------------
101  void AddOperation( Operation<true> *operation );
102 
103  //------------------------------------------------------------------------
110  //------------------------------------------------------------------------
111  void Assign( std::promise<XRootDStatus> prms,
112  std::function<void(const XRootDStatus&)> final );
113 
114  private:
115 
116  //------------------------------------------------------------------------
118  //------------------------------------------------------------------------
119  void HandleResponseImpl( XRootDStatus *status, AnyObject *response,
120  HostList *hostList = nullptr );
121 
122  inline void dealloc( XRootDStatus *status, AnyObject *response,
123  HostList *hostList )
124  {
125  delete status;
126  delete response;
127  delete hostList;
128  }
129 
130  //------------------------------------------------------------------------
132  //------------------------------------------------------------------------
133  std::unique_ptr<ResponseHandler> responseHandler;
134 
135  //------------------------------------------------------------------------
137  //------------------------------------------------------------------------
138  std::unique_ptr<Operation<true>> nextOperation;
139 
140  //------------------------------------------------------------------------
142  //------------------------------------------------------------------------
143  std::promise<XRootDStatus> prms;
144 
145  //------------------------------------------------------------------------
148  //------------------------------------------------------------------------
149  std::function<void(const XRootDStatus&)> final;
150 
151  //------------------------------------------------------------------------
153  //------------------------------------------------------------------------
155  };
156 
157  //----------------------------------------------------------------------------
163  //----------------------------------------------------------------------------
164  template<bool HasHndl>
165  class Operation
166  {
167  // Declare friendship between templates
168  template<bool>
169  friend class Operation;
170 
171  friend std::future<XRootDStatus> Async( Pipeline );
172 
173  friend class Pipeline;
174  friend class PipelineHandler;
175 
176  public:
177 
178  //------------------------------------------------------------------------
180  //------------------------------------------------------------------------
181  Operation() : valid( true )
182  {
183  }
184 
185  //------------------------------------------------------------------------
187  //------------------------------------------------------------------------
188  template<bool from>
190  handler( std::move( op.handler ) ), valid( true )
191  {
192  if( !op.valid ) throw std::invalid_argument( "Cannot construct "
193  "Operation from an invalid Operation!" );
194  op.valid = false;
195  }
196 
197  //------------------------------------------------------------------------
199  //------------------------------------------------------------------------
200  virtual ~Operation()
201  {
202  }
203 
204  //------------------------------------------------------------------------
206  //------------------------------------------------------------------------
207  virtual std::string ToString() = 0;
208 
209  //------------------------------------------------------------------------
213  //------------------------------------------------------------------------
214  virtual Operation<HasHndl>* Move() = 0;
215 
216  //------------------------------------------------------------------------
221  //------------------------------------------------------------------------
222  virtual Operation<true>* ToHandled() = 0;
223 
224  protected:
225 
226  //------------------------------------------------------------------------
236  //------------------------------------------------------------------------
237  void Run( std::promise<XRootDStatus> prms,
238  std::function<void(const XRootDStatus&)> final )
239  {
240  static_assert(HasHndl, "Only an operation that has a handler can be assigned to workflow");
241  handler->Assign( std::move( prms ), std::move( final ) );
242  XRootDStatus st = RunImpl();
243  if( st.IsOK() ) handler.release();
244  else
245  ForceHandler( st );
246  }
247 
248  //------------------------------------------------------------------------
255  //------------------------------------------------------------------------
256  virtual XRootDStatus RunImpl() = 0;
257 
258  //------------------------------------------------------------------------
265  //------------------------------------------------------------------------
266  void ForceHandler( const XRootDStatus &status )
267  {
268  handler->HandleResponse( new XRootDStatus( status ), nullptr );
269  // HandleResponse already freed the memory so we have to
270  // release the unique pointer
271  handler.release();
272  }
273 
274  //------------------------------------------------------------------------
278  //------------------------------------------------------------------------
280  {
281  if( handler )
282  handler->AddOperation( op );
283  }
284 
285  //------------------------------------------------------------------------
287  //------------------------------------------------------------------------
288  std::unique_ptr<PipelineHandler> handler;
289 
290  //------------------------------------------------------------------------
292  //------------------------------------------------------------------------
293  bool valid;
294  };
295 
296  //----------------------------------------------------------------------------
302  //----------------------------------------------------------------------------
303  class Pipeline
304  {
305  template<bool> friend class ParallelOperation;
306  friend std::future<XRootDStatus> Async( Pipeline );
307 
308  public:
309 
310  //------------------------------------------------------------------------
312  //------------------------------------------------------------------------
314  operation( op->Move() )
315  {
316 
317  }
318 
319  //------------------------------------------------------------------------
321  //------------------------------------------------------------------------
323  operation( op.Move() )
324  {
325 
326  }
327 
328  //------------------------------------------------------------------------
330  //------------------------------------------------------------------------
332  operation( op.Move() )
333  {
334 
335  }
336 
338  operation( op->ToHandled() )
339  {
340 
341  }
342 
343  //------------------------------------------------------------------------
345  //------------------------------------------------------------------------
347  operation( op.ToHandled() )
348  {
349 
350  }
351 
352  //------------------------------------------------------------------------
354  //------------------------------------------------------------------------
356  operation( op.ToHandled() )
357  {
358 
359  }
360 
361  Pipeline( Pipeline &&pipe ) :
362  operation( std::move( pipe.operation ) )
363  {
364 
365  }
366 
367  //------------------------------------------------------------------------
369  //------------------------------------------------------------------------
371  {
372  operation = std::move( pipe.operation );
373  return *this;
374  }
375 
376  //------------------------------------------------------------------------
380  //------------------------------------------------------------------------
381  operator Operation<true>&()
382  {
383  if( !bool( operation ) ) throw std::logic_error( "Invalid pipeline." );
384  return *operation.get();
385  }
386 
387  //------------------------------------------------------------------------
391  //------------------------------------------------------------------------
392  operator bool()
393  {
394  return bool( operation );
395  }
396 
397  private:
398 
399  //------------------------------------------------------------------------
404  //------------------------------------------------------------------------
406  {
407  return operation.get();
408  }
409 
410  //------------------------------------------------------------------------
416  //------------------------------------------------------------------------
417  void Run( std::function<void(const XRootDStatus&)> final = nullptr )
418  {
419  if( ftr.valid() )
420  throw std::logic_error( "Pipeline is already running" );
421 
422  // a promise that the pipe will have a result
423  std::promise<XRootDStatus> prms;
424  ftr = prms.get_future();
425  operation->Run( std::move( prms ), std::move( final ) );
426  }
427 
428  //------------------------------------------------------------------------
430  //------------------------------------------------------------------------
431  std::unique_ptr<Operation<true>> operation;
432 
433  //------------------------------------------------------------------------
435  //------------------------------------------------------------------------
436  std::future<XRootDStatus> ftr;
437 
438  };
439 
440  //----------------------------------------------------------------------------
446  //----------------------------------------------------------------------------
447  inline std::future<XRootDStatus> Async( Pipeline pipeline )
448  {
449  pipeline.Run();
450  return std::move( pipeline.ftr );
451  }
452 
453  //----------------------------------------------------------------------------
460  //----------------------------------------------------------------------------
461  inline XRootDStatus WaitFor( Pipeline pipeline )
462  {
463  return Async( std::move( pipeline ) ).get();
464  }
465 
466  //----------------------------------------------------------------------------
473  //----------------------------------------------------------------------------
474  template<template<bool> class Derived, bool HasHndl, typename HdlrFactory, typename ... Args>
475  class ConcreteOperation: public Operation<HasHndl>
476  {
477  template<template<bool> class, bool, typename, typename ...>
478  friend class ConcreteOperation;
479 
480  public:
481 
482  //------------------------------------------------------------------------
486  //------------------------------------------------------------------------
487  ConcreteOperation( Args&&... args ) : args( std::tuple<Args...>( std::move( args )... ) )
488  {
489  static_assert( !HasHndl, "It is only possible to construct operation without handler" );
490  }
491 
492  //------------------------------------------------------------------------
498  //------------------------------------------------------------------------
499  template<bool from>
501  Operation<HasHndl>( std::move( op ) ), args( std::move( op.args ) )
502  {
503 
504  }
505 
506  //------------------------------------------------------------------------
514  //------------------------------------------------------------------------
515  template<typename Hdlr>
516  Derived<true> operator>>( Hdlr &&hdlr )
517  {
518  return this->StreamImpl( HdlrFactory::Create( hdlr ) );
519  }
520 
521  //------------------------------------------------------------------------
527  //------------------------------------------------------------------------
528  Derived<true> operator|( Operation<true> &op )
529  {
530  return PipeImpl( *this, op );
531  }
532 
533  //------------------------------------------------------------------------
539  //------------------------------------------------------------------------
540  Derived<true> operator|( Operation<true> &&op )
541  {
542  return PipeImpl( *this, op );
543  }
544 
545  //------------------------------------------------------------------------
551  //------------------------------------------------------------------------
552  Derived<true> operator|( Operation<false> &op )
553  {
554  return PipeImpl( *this, op );
555  }
556 
557  //------------------------------------------------------------------------
563  //------------------------------------------------------------------------
564  Derived<true> operator|( Operation<false> &&op )
565  {
566  return PipeImpl( *this, op );
567  }
568 
569  //------------------------------------------------------------------------
571  //------------------------------------------------------------------------
572  Derived<HasHndl> Recovery( rcvry_func recovery )
573  {
574  this->recovery = std::move( recovery );
575  return Transform<HasHndl>();
576  }
577 
578  //------------------------------------------------------------------------
582  //------------------------------------------------------------------------
584  {
585  Derived<HasHndl> *me = static_cast<Derived<HasHndl>*>( this );
586  return new Derived<HasHndl>( std::move( *me ) );
587  }
588 
589  //------------------------------------------------------------------------
593  //------------------------------------------------------------------------
595  {
596  this->handler.reset( new PipelineHandler( std::move( this->recovery ) ) );
597  Derived<HasHndl> *me = static_cast<Derived<HasHndl>*>( this );
598  return new Derived<true>( std::move( *me ) );
599  }
600 
601  protected:
602 
603  //------------------------------------------------------------------------
607  //------------------------------------------------------------------------
608  template<bool to>
609  inline Derived<to> Transform()
610  {
611  Derived<HasHndl> *me = static_cast<Derived<HasHndl>*>( this );
612  return Derived<to>( std::move( *me ) );
613  }
614 
615  //------------------------------------------------------------------------
621  //------------------------------------------------------------------------
622  inline Derived<true> StreamImpl( ResponseHandler *handler )
623  {
624  static_assert( !HasHndl, "Operator >> is available only for operation without handler" );
625  this->handler.reset( new PipelineHandler( handler, std::move( this->recovery ) ) );
626  return Transform<true>();
627  }
628 
629  //------------------------------------------------------------------------
636  //------------------------------------------------------------------------
637  inline static
638  Derived<true> PipeImpl( ConcreteOperation<Derived, true, HdlrFactory,
639  Args...> &me, Operation<true> &op )
640  {
641  me.AddOperation( op.Move() );
642  return me.template Transform<true>();
643  }
644 
645  //------------------------------------------------------------------------
652  //------------------------------------------------------------------------
653  inline static
654  Derived<true> PipeImpl( ConcreteOperation<Derived, true, HdlrFactory,
655  Args...> &me, Operation<false> &op )
656  {
657  me.AddOperation( op.ToHandled() );
658  return me.template Transform<true>();
659  }
660 
661  //------------------------------------------------------------------------
668  //------------------------------------------------------------------------
669  inline static
670  Derived<true> PipeImpl( ConcreteOperation<Derived, false, HdlrFactory,
671  Args...> &me, Operation<true> &op )
672  {
673  me.handler.reset( new PipelineHandler( std::move( me.recovery ) ) );
674  me.AddOperation( op.Move() );
675  return me.template Transform<true>();
676  }
677 
678  //------------------------------------------------------------------------
685  //------------------------------------------------------------------------
686  inline static
687  Derived<true> PipeImpl( ConcreteOperation<Derived, false, HdlrFactory,
688  Args...> &me, Operation<false> &op )
689  {
690  me.handler.reset( new PipelineHandler( std::move( me.recovery ) ) );
691  me.AddOperation( op.ToHandled() );
692  return me.template Transform<true>();
693  }
694 
695  //------------------------------------------------------------------------
697  //------------------------------------------------------------------------
698  std::tuple<Args...> args;
699 
700  //------------------------------------------------------------------------
702  //------------------------------------------------------------------------
703 
705  };
706 }
707 
708 #endif // __XRD_CL_OPERATIONS_HH__
XrdClOperationHandlers.hh
XrdClXRootDResponses.hh
XrdCl::ResponseHandler
Handle an async response.
Definition: XrdClXRootDResponses.hh:975
XrdCl::Operation::RunImpl
virtual XRootDStatus RunImpl()=0
XrdCl::WaitFor
XRootDStatus WaitFor(Pipeline pipeline)
Definition: XrdClOperations.hh:461
XrdCl::Pipeline::Run
void Run(std::function< void(const XRootDStatus &)> final=nullptr)
Definition: XrdClOperations.hh:417
XrdCl::Pipeline::ftr
std::future< XRootDStatus > ftr
The future result of the pipeline.
Definition: XrdClOperations.hh:436
XrdCl::Operation::AddOperation
void AddOperation(Operation< true > *op)
Definition: XrdClOperations.hh:279
XrdCl::ConcreteOperation::StreamImpl
Derived< true > StreamImpl(ResponseHandler *handler)
Definition: XrdClOperations.hh:622
XrdCl::PipelineHandler::recovery
rcvry_func recovery
The recovery routine for the respective operation.
Definition: XrdClOperations.hh:154
XrdCl::ConcreteOperation::PipeImpl
static Derived< true > PipeImpl(ConcreteOperation< Derived, false, HdlrFactory, Args... > &me, Operation< false > &op)
Definition: XrdClOperations.hh:687
XrdSysPthread.hh
XrdCl::Pipeline::operation
std::unique_ptr< Operation< true > > operation
First operation in the pipeline.
Definition: XrdClOperations.hh:431
XrdCl::Operation::Run
void Run(std::promise< XRootDStatus > prms, std::function< void(const XRootDStatus &)> final)
Definition: XrdClOperations.hh:237
XrdCl::ConcreteOperation::operator>>
Derived< true > operator>>(Hdlr &&hdlr)
Definition: XrdClOperations.hh:516
XrdCl::ConcreteOperation::PipeImpl
static Derived< true > PipeImpl(ConcreteOperation< Derived, false, HdlrFactory, Args... > &me, Operation< true > &op)
Definition: XrdClOperations.hh:670
XrdCl::Pipeline::operator=
Pipeline & operator=(Pipeline &&pipe)
Constructor.
Definition: XrdClOperations.hh:370
XrdCl::ConcreteOperation::ConcreteOperation
ConcreteOperation(ConcreteOperation< Derived, from, HdlrFactory, Args... > &&op)
Definition: XrdClOperations.hh:500
XrdCl::ConcreteOperation::ConcreteOperation
ConcreteOperation(Args &&... args)
Definition: XrdClOperations.hh:487
XrdCl::Operation::Operation
Operation(Operation< from > &&op)
Move constructor between template instances.
Definition: XrdClOperations.hh:189
XrdCl::PipelineHandler
Definition: XrdClOperations.hh:57
XrdCl::ConcreteOperation::operator|
Derived< true > operator|(Operation< false > &&op)
Definition: XrdClOperations.hh:564
XrdCl::Operation::handler
std::unique_ptr< PipelineHandler > handler
Operation handler.
Definition: XrdClOperations.hh:288
XrdCl::PipelineHandler::HandleResponseWithHosts
void HandleResponseWithHosts(XRootDStatus *status, AnyObject *response, HostList *hostList)
Callback function.
XrdCl::PipelineHandler::AddOperation
void AddOperation(Operation< true > *operation)
XrdCl::Pipeline::Pipeline
Pipeline(Operation< true > &&op)
Constructor.
Definition: XrdClOperations.hh:331
XrdCl::ConcreteOperation::ToHandled
Operation< true > * ToHandled()
Definition: XrdClOperations.hh:594
XrdCl::Operation::Async
friend std::future< XRootDStatus > Async(Pipeline)
Definition: XrdClOperations.hh:447
XrdCl::ConcreteOperation::args
std::tuple< Args... > args
Operation arguments.
Definition: XrdClOperations.hh:698
XrdCl::PipelineHandler::PipelineHandler
PipelineHandler(rcvry_func &&recovery)
Default Constructor.
Definition: XrdClOperations.hh:74
XrdCl::ConcreteOperation
Definition: XrdClOperations.hh:476
XrdCl::ParallelOperation
Definition: XrdClParallelOperation.hh:73
XrdCl::Pipeline::Pipeline
Pipeline(Operation< false > &op)
Constructor.
Definition: XrdClOperations.hh:346
XrdCl::PipelineHandler::HandleResponse
void HandleResponse(XRootDStatus *status, AnyObject *response)
Callback function.
XrdCl::XRootDStatus
Request status.
Definition: XrdClXRootDResponses.hh:215
XrdCl::ConcreteOperation::operator|
Derived< true > operator|(Operation< true > &op)
Definition: XrdClOperations.hh:528
XrdCl::ConcreteOperation::ConcreteOperation
friend class ConcreteOperation
Definition: XrdClOperations.hh:478
XrdCl::PipelineHandler::HandleResponseImpl
void HandleResponseImpl(XRootDStatus *status, AnyObject *response, HostList *hostList=nullptr)
Callback function implementation;.
XrdCl::Operation::ToHandled
virtual Operation< true > * ToHandled()=0
XrdCl::Operation::ForceHandler
void ForceHandler(const XRootDStatus &status)
Definition: XrdClOperations.hh:266
XrdCl::Pipeline::Pipeline
Pipeline(Pipeline &&pipe)
Definition: XrdClOperations.hh:361
XrdCl::Pipeline
Definition: XrdClOperations.hh:304
XrdCl::Status::IsOK
bool IsOK() const
We're fine.
Definition: XrdClStatus.hh:120
XrdCl::Operation::~Operation
virtual ~Operation()
Destructor.
Definition: XrdClOperations.hh:200
XrdCl::ConcreteOperation::Move
Operation< HasHndl > * Move()
Definition: XrdClOperations.hh:583
XrdCl::PipelineHandler::Assign
void Assign(std::promise< XRootDStatus > prms, std::function< void(const XRootDStatus &)> final)
XrdCl::Operation::ToString
virtual std::string ToString()=0
Name of the operation.
XrdCl::PipelineHandler::responseHandler
std::unique_ptr< ResponseHandler > responseHandler
The handler of our operation.
Definition: XrdClOperations.hh:133
XrdCl
Definition: XrdClAnyObject.hh:26
XrdCl::PipelineHandler::dealloc
void dealloc(XRootDStatus *status, AnyObject *response, HostList *hostList)
Definition: XrdClOperations.hh:122
XrdCl::HostList
std::vector< HostInfo > HostList
Definition: XrdClXRootDResponses.hh:969
XrdCl::ConcreteOperation::PipeImpl
static Derived< true > PipeImpl(ConcreteOperation< Derived, true, HdlrFactory, Args... > &me, Operation< true > &op)
Definition: XrdClOperations.hh:638
XrdCl::PipelineHandler::PipelineHandler
PipelineHandler(ResponseHandler *handler, rcvry_func &&recovery)
XrdCl::Operation
Definition: XrdClOperations.hh:166
XrdCl::Pipeline::operator->
Operation< true > * operator->()
Definition: XrdClOperations.hh:405
XrdClArg.hh
XrdCl::Operation::Operation
Operation()
Constructor.
Definition: XrdClOperations.hh:181
XrdCl::Pipeline::Pipeline
Pipeline(Operation< true > &op)
Constructor.
Definition: XrdClOperations.hh:322
XrdCl::Operation::PipelineHandler
friend class PipelineHandler
Definition: XrdClOperations.hh:174
XrdCl::Async
std::future< XRootDStatus > Async(Pipeline pipeline)
Definition: XrdClOperations.hh:447
XrdCl::ConcreteOperation::recovery
rcvry_func recovery
The recovery routine for this operation.
Definition: XrdClOperations.hh:704
XrdCl::Pipeline::Pipeline
Pipeline(Operation< true > *op)
Constructor.
Definition: XrdClOperations.hh:313
XrdCl::Pipeline::Async
friend std::future< XRootDStatus > Async(Pipeline)
Definition: XrdClOperations.hh:447
XrdCl::PipelineHandler::nextOperation
std::unique_ptr< Operation< true > > nextOperation
Next operation in the pipeline.
Definition: XrdClOperations.hh:138
XrdCl::Operation::Move
virtual Operation< HasHndl > * Move()=0
XrdCl::Pipeline::Pipeline
Pipeline(Operation< false > *op)
Definition: XrdClOperations.hh:337
XrdCl::PipelineHandler::~PipelineHandler
~PipelineHandler()
Destructor.
Definition: XrdClOperations.hh:92
XrdCl::ConcreteOperation::PipeImpl
static Derived< true > PipeImpl(ConcreteOperation< Derived, true, HdlrFactory, Args... > &me, Operation< false > &op)
Definition: XrdClOperations.hh:654
XrdCl::ConcreteOperation::Recovery
Derived< HasHndl > Recovery(rcvry_func recovery)
Set recovery procedure in case the operation fails.
Definition: XrdClOperations.hh:572
XrdCl::ConcreteOperation::operator|
Derived< true > operator|(Operation< true > &&op)
Definition: XrdClOperations.hh:540
XrdCl::AnyObject
Definition: XrdClAnyObject.hh:33
XrdCl::ConcreteOperation::operator|
Derived< true > operator|(Operation< false > &op)
Definition: XrdClOperations.hh:552
XrdCl::rcvry_func
std::function< Operation< true > *(const XRootDStatus &)> rcvry_func
Type of the recovery function to be provided by the user.
Definition: XrdClOperations.hh:44
XrdCl::Operation::valid
bool valid
Flag indicating if it is a valid object.
Definition: XrdClOperations.hh:293
XrdCl::PipelineHandler::prms
std::promise< XRootDStatus > prms
The promise that there will be a result (traveling along the pipeline)
Definition: XrdClOperations.hh:143
XrdCl::ConcreteOperation::Transform
Derived< to > Transform()
Definition: XrdClOperations.hh:609
XrdCl::Pipeline::Pipeline
Pipeline(Operation< false > &&op)
Constructor.
Definition: XrdClOperations.hh:355