blob: a02f675eae5bf778d42fd314c86beb6a24ed2797 [file] [log] [blame]
Shuo Chen29c77fe2014-03-18 11:29:41 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev42290b22017-03-09 12:58:29 -08003 * Copyright (c) 2014-2017, Regents of the University of California.
Alexander Afanasyeve1e6f2a2014-04-25 11:28:12 -07004 *
5 * This file is part of NDN repo-ng (Next generation of NDN repository).
6 * See AUTHORS.md for complete list of repo-ng authors and contributors.
7 *
8 * repo-ng is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * repo-ng, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Shuo Chen29c77fe2014-03-18 11:29:41 -070018 */
19
Alexander Afanasyev39d98072014-05-04 12:46:29 -070020#ifndef REPO_HANDLES_WRITE_HANDLE_HPP
21#define REPO_HANDLES_WRITE_HANDLE_HPP
Shuo Chen29c77fe2014-03-18 11:29:41 -070022
Shuo Chen29c77fe2014-03-18 11:29:41 -070023#include "base-handle.hpp"
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -070024
Weiqi Shif0330d52014-07-09 10:54:27 -070025#include <ndn-cxx/security/validator-config.hpp>
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -070026
Shuo Chen29c77fe2014-03-18 11:29:41 -070027#include <queue>
28
29namespace repo {
30
31using std::map;
32using std::pair;
33using std::queue;
34
35/**
Alexander Afanasyeve1e6f2a2014-04-25 11:28:12 -070036 * @brief WriteHandle provides basic credit based congestion control.
37 *
38 * First repo sends interests of credit number and then credit will be 0.
39 *
40 * If a data comes, credit++ and sends a interest then credit--.
41 *
42 * If the interest timeout, repo will retry and send interest in retrytimes.
43 *
44 * If one interest timeout beyond retrytimes, the fetching process will terminate.
45 *
46 * Another case is that if command will insert segmented data without EndBlockId.
47 *
48 * The repo will keep fetching data in noendTimeout time.
49 *
50 * If data returns with FinalBlockId, this detecting timeout process will terminate.
51 *
52 * If client sends a insert check command, the noendTimeout timer will be set to 0.
53 *
54 * If repo cannot get FinalBlockId in noendTimeout time, the fetching process will terminate.
55 */
Shuo Chen29c77fe2014-03-18 11:29:41 -070056class WriteHandle : public BaseHandle
57{
58
59public:
60 class Error : public BaseHandle::Error
61 {
62 public:
63 explicit
64 Error(const std::string& what)
65 : BaseHandle::Error(what)
66 {
67 }
68 };
69
70
71public:
Weiqi Shif0330d52014-07-09 10:54:27 -070072 WriteHandle(Face& face, RepoStorage& storageHandle, KeyChain& keyChain,
Shuo Chen028dcd32014-06-21 16:36:44 +080073 Scheduler& scheduler, ValidatorConfig& validator);
Shuo Chen29c77fe2014-03-18 11:29:41 -070074
75 virtual void
76 listen(const Name& prefix);
77
78private:
79 /**
80 * @brief Information of insert process including variables for response
81 * and credit based flow control
82 */
83 struct ProcessInfo
84 {
85 //ProcessId id;
86 RepoCommandResponse response;
87 queue<SegmentNo> nextSegmentQueue; ///< queue of waiting segment
88 /// to be sent when having credits
89 SegmentNo nextSegment; ///< last segment put into the nextSegmentQueue
90 map<SegmentNo, int> retryCounts; ///< to store retrying times of timeout segment
91 int credit; ///< congestion control credits of process
92
93 /**
94 * @brief the latest time point at which EndBlockId must be determined
95 *
96 * Segmented fetch process will terminate if EndBlockId cannot be
97 * determined before this time point.
98 * It is initialized to now()+noEndTimeout when segmented fetch process begins,
99 * and reset to now()+noEndTimeout each time an insert status check command is processed.
100 */
101 ndn::time::steady_clock::TimePoint noEndTime;
102 };
103
104private: // insert command
105 /**
106 * @brief handle insert commands
107 */
108 void
109 onInterest(const Name& prefix, const Interest& interest);
110
111 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700112 onValidated(const std::shared_ptr<const Interest>& interest, const Name& prefix);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700113
114 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700115 onValidationFailed(const std::shared_ptr<const Interest>& interest, const std::string& reason);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700116
117 /**
118 * @brief insert command prefix register failed
119 */
120 void
121 onRegisterFailed(const Name& prefix, const std::string& reason);
122
123private: // single data fetching
124 /**
125 * @brief fetch one data
126 */
127 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800128 onData(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700129
Shuo Chenc88c87d2014-06-25 20:21:02 +0800130 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700131 onDataValidated(const Interest& interest, const std::shared_ptr<const Data>& data,
Shuo Chenc88c87d2014-06-25 20:21:02 +0800132 ProcessId processId);
133
Shuo Chen29c77fe2014-03-18 11:29:41 -0700134 /**
135 * @brief handle when fetching one data timeout
136 */
137 void
138 onTimeout(const Interest& interest, ProcessId processId);
139
140 void
141 processSingleInsertCommand(const Interest& interest, RepoCommandParameter& parameter);
142
143private: // segmented data fetching
144 /**
145 * @brief fetch segmented data
146 */
147 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800148 onSegmentData(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700149
Shuo Chenc88c87d2014-06-25 20:21:02 +0800150 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700151 onSegmentDataValidated(const Interest& interest, const std::shared_ptr<const Data>& data,
Shuo Chenc88c87d2014-06-25 20:21:02 +0800152 ProcessId processId);
153
Shuo Chen29c77fe2014-03-18 11:29:41 -0700154 /**
155 * @brief Timeout when fetching segmented data. Data can be fetched RETRY_TIMEOUT times.
156 */
157 void
158 onSegmentTimeout(const Interest& interest, ProcessId processId);
159
160 /**
161 * @brief initiate fetching segmented data
162 */
163 void
164 segInit(ProcessId processId, const RepoCommandParameter& parameter);
165
166 /**
167 * @brief control for sending interests in function onSegmentData()
168 */
169 void
170 onSegmentDataControl(ProcessId processId, const Interest& interest);
171
172 /**
173 * @brief control for sending interest in function onSegmentTimeout
174 */
175 void
176 onSegmentTimeoutControl(ProcessId processId, const Interest& interest);
177
178 void
179 processSegmentedInsertCommand(const Interest& interest, RepoCommandParameter& parameter);
180
Shuo Chenc88c87d2014-06-25 20:21:02 +0800181private:
182 /**
183 * @brief failure of validation for both one or segmented data
184 */
185 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700186 onDataValidationFailed(const std::shared_ptr<const Data>& data, const std::string& reason);
Shuo Chenc88c87d2014-06-25 20:21:02 +0800187
Shuo Chen29c77fe2014-03-18 11:29:41 -0700188 /**
189 * @brief extends noEndTime of process if not noEndTimeout, set StatusCode 405
190 *
191 * called by onCheckValidated() if there is no EndBlockId. If not noEndTimeout,
192 * extends noEndTime of process. If noEndTimeout, set status code 405 as noEndTimeout.
193 */
194 void
195 extendNoEndTime(ProcessInfo& process);
196
197private: // insert state check command
198 /**
199 * @brief handle insert check command
200 */
201 void
202 onCheckInterest(const Name& prefix, const Interest& interest);
203
204 /**
205 * @brief insert check command prefix register failed
206 */
207 void
208 onCheckRegisterFailed(const Name& prefix, const std::string& reason);
209
210 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700211 onCheckValidated(const std::shared_ptr<const Interest>& interest, const Name& prefix);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700212
213 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700214 onCheckValidationFailed(const std::shared_ptr<const Interest>& interest,
215 const std::string& reason);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700216
217private:
218 void
219 deleteProcess(ProcessId processId);
220
221 /**
222 * @brief schedule a event to delete the process
223 */
224 void
225 deferredDeleteProcess(ProcessId processId);
226
227 void
228 negativeReply(const Interest& interest, int statusCode);
229
230private:
231
Shuo Chen028dcd32014-06-21 16:36:44 +0800232 ValidatorConfig& m_validator;
Shuo Chen29c77fe2014-03-18 11:29:41 -0700233
234 map<ProcessId, ProcessInfo> m_processes;
235
236 int m_retryTime;
237 int m_credit;
238 ndn::time::milliseconds m_noEndTimeout;
Weiqi Shi098f91c2014-07-23 17:41:35 -0700239 ndn::time::milliseconds m_interestLifetime;
Shuo Chen29c77fe2014-03-18 11:29:41 -0700240};
241
242} // namespace repo
243
Alexander Afanasyev39d98072014-05-04 12:46:29 -0700244#endif // REPO_HANDLES_WRITE_HANDLE_HPP