TapeServerReporter.hpp 4.93 KB
Newer Older
1
2
/*
 * @project        The CERN Tape Archive (CTA)
3
 * @copyright      Copyright(C) 2003-2021 CERN
4
5
6
7
 * @license        This program is free software: you can redistribute it and/or modify
 *                 it under the terms of the GNU General Public License as published by
 *                 the Free Software Foundation, either version 3 of the License, or
 *                 (at your option) any later version.
8
 *
9
10
11
12
 *                 This program 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 General Public License for more details.
13
 *
14
15
16
 *                 You should have received a copy of the GNU General Public License
 *                 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
17
18
19

#pragma once

20
#include "common/threading/Thread.hpp"
21
#include "common/threading/BlockingQueue.hpp"
22
#include "castor/tape/tapeserver/daemon/VolumeInfo.hpp"
Victor Kotlyar's avatar
Victor Kotlyar committed
23
#include "common/log/LogContext.hpp"
24
25
#include "tapeserver/session/SessionState.hpp"
#include "tapeserver/session/SessionType.hpp"
26
#include "tapeserver/daemon/TpconfigLine.hpp"
27
#include <memory>
28
29
#include <string>
#include <stdint.h>
30
31

namespace castor {
32
33
34
namespace messages{
    class TapeserverProxy;
  }
35
namespace tape {
36
37
namespace tapeserver {
namespace daemon {
38
  
39
class TapeServerReporter : private cta::threading::Thread {
40
41
42

public:
  /**
43
   * COnstructor
44
   * @param tapeserverProxy
45
   * @param driveConfig The configuration of the tape drive we are using.
46
   * @param hostname The host name of the computer
47
   * @param volume The volume information from the client
48
   * @param lc 
49
   */
50
  TapeServerReporter(
51
    cta::tape::daemon::TapedProxy& tapeserverProxy,
52
    const cta::tape::daemon::TpconfigLine &driveConfig,
53
    const std::string &hostname,
54
    const castor::tape::tapeserver::daemon::VolumeInfo &volume,
Victor Kotlyar's avatar
Victor Kotlyar committed
55
    cta::log::LogContext lc);
56
57
  
  /**
58
59
   * Put into the waiting list a guard value to signal the thread we want
   * to stop
60
61
   */      
  void finish();
62
  
63
  /**
64
   * Will call TapedProxy::reportState();
65
   */
66
67
68
  void reportState(cta::tape::session::SessionState state, 
      cta::tape::session::SessionType type);

69
  /**
70
71
   * Special function managing the special case of retrieves, where disk and
   * tape thread can finish in different orders (tape part)
72
   */
73
  void reportTapeUnmountedForRetrieve();
74
75
  
  /**
76
77
   * Special function managing the special case of retrieves, where disk and
   * tape thread can finish in different orders (disk part)
78
   */
79
80
81
  void reportDiskCompleteForRetrieve();

//------------------------------------------------------------------------------
82
83
84
  //start and wait for thread to finish
  void startThreads();
  void waitThreads();
85
    
86
private:
87
  bool m_threadRunnig;
88
89
90
91
92
93
94
95
96
97
98
  /*
  This internal mechanism could (should ?) be easily changed to a queue 
   * of {std/boost}::function coupled with bind. For instance, tapeMountedForWrite
   * should look like 
   *   m_fifo.push(bind(m_tapeserverProxy,&tapeMountedForWrite,args...))
   * and execute
   *  while(1)
   *   (m_fifo.push())();
   * But no tr1 neither boost, so, another time ...
  */
  
99
100
101
  class Report {
  public:
    virtual ~Report(){}
102
    virtual void execute(TapeServerReporter&)=0;
103
  };
104
105
  
  class ReportStateChange: public Report {
106
  public:
107
108
109
110
111
112
    ReportStateChange(cta::tape::session::SessionState state, 
      cta::tape::session::SessionType type);
    void execute(TapeServerReporter&) override;
  private:
    cta::tape::session::SessionState m_state;
    cta::tape::session::SessionType m_type;
113
  };
114
115
  
  class ReportTapeUnmountedForRetrieve: public Report {
116
  public:
117
    void execute(TapeServerReporter&) override;
118
  };
119
120
  
  class ReportDiskCompleteForRetrieve: public Report {
121
  public:
122
    void execute(TapeServerReporter&) override;
123
  };
124
125
126
127
128
129
130
131
132
  /**
   * Inherited from Thread, it will do the job : pop a request, execute it 
   * and delete it
   */
  virtual void run();
  
  /** 
   * m_fifo is holding all the report waiting to be processed
   */
133
  cta::threading::BlockingQueue<Report*> m_fifo;
134
135
136
137
138
  
  /**
   A bunch of references to proxies to send messages to the 
   * outside world when we have to
   */
139
  cta::tape::daemon::TapedProxy& m_tapeserverProxy;
140
  
141
142
143
  /**
   * Log context, copied because it is in a separated thread
   */
Victor Kotlyar's avatar
Victor Kotlyar committed
144
  cta::log::LogContext m_lc;
145
146
147
148
149
150
151
152
153
154
155
156
  
  /**
   * Boolean allowing the management of the special case of recall where
   * end of tape and disk threads can happen in any order (tape side)
   */
  bool m_tapeUnmountedForRecall = false;
  
  /**
   * Boolean allowing the management of the special case of recall where
   * end of tape and disk threads can happen in any order (disk side)
   */
  bool m_diskCompleteForRecall = false;
157

158
159
  const std::string m_server;
  const std::string m_unitName;
160
  const std::string m_logicalLibrary;
161
  const castor::tape::tapeserver::daemon::VolumeInfo m_volume;
162
  const pid_t m_sessionPid;
163

164
165
166
};

}}}}