blob: 13474700613f59a9769ecf55f82bc2e85b0cef82 [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
Shuo Chen29c77fe2014-03-18 11:29:41 -070025#include <queue>
26
27namespace repo {
28
29using std::map;
30using std::pair;
31using std::queue;
32
33/**
Alexander Afanasyeve1e6f2a2014-04-25 11:28:12 -070034 * @brief WriteHandle provides basic credit based congestion control.
35 *
36 * First repo sends interests of credit number and then credit will be 0.
37 *
38 * If a data comes, credit++ and sends a interest then credit--.
39 *
40 * If the interest timeout, repo will retry and send interest in retrytimes.
41 *
42 * If one interest timeout beyond retrytimes, the fetching process will terminate.
43 *
44 * Another case is that if command will insert segmented data without EndBlockId.
45 *
46 * The repo will keep fetching data in noendTimeout time.
47 *
48 * If data returns with FinalBlockId, this detecting timeout process will terminate.
49 *
50 * If client sends a insert check command, the noendTimeout timer will be set to 0.
51 *
52 * If repo cannot get FinalBlockId in noendTimeout time, the fetching process will terminate.
53 */
Shuo Chen29c77fe2014-03-18 11:29:41 -070054class WriteHandle : public BaseHandle
55{
56
57public:
58 class Error : public BaseHandle::Error
59 {
60 public:
61 explicit
62 Error(const std::string& what)
63 : BaseHandle::Error(what)
64 {
65 }
66 };
67
68
69public:
Weiqi Shif0330d52014-07-09 10:54:27 -070070 WriteHandle(Face& face, RepoStorage& storageHandle, KeyChain& keyChain,
Junxiao Shi047a6fb2017-06-08 16:16:05 +000071 Scheduler& scheduler, Validator& validator);
Shuo Chen29c77fe2014-03-18 11:29:41 -070072
73 virtual void
74 listen(const Name& prefix);
75
76private:
77 /**
78 * @brief Information of insert process including variables for response
79 * and credit based flow control
80 */
81 struct ProcessInfo
82 {
83 //ProcessId id;
84 RepoCommandResponse response;
85 queue<SegmentNo> nextSegmentQueue; ///< queue of waiting segment
86 /// to be sent when having credits
87 SegmentNo nextSegment; ///< last segment put into the nextSegmentQueue
88 map<SegmentNo, int> retryCounts; ///< to store retrying times of timeout segment
89 int credit; ///< congestion control credits of process
90
91 /**
92 * @brief the latest time point at which EndBlockId must be determined
93 *
94 * Segmented fetch process will terminate if EndBlockId cannot be
95 * determined before this time point.
96 * It is initialized to now()+noEndTimeout when segmented fetch process begins,
97 * and reset to now()+noEndTimeout each time an insert status check command is processed.
98 */
99 ndn::time::steady_clock::TimePoint noEndTime;
100 };
101
102private: // insert command
103 /**
104 * @brief handle insert commands
105 */
106 void
107 onInterest(const Name& prefix, const Interest& interest);
108
109 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700110 onValidated(const std::shared_ptr<const Interest>& interest, const Name& prefix);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700111
112 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700113 onValidationFailed(const std::shared_ptr<const Interest>& interest, const std::string& reason);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700114
115 /**
116 * @brief insert command prefix register failed
117 */
118 void
119 onRegisterFailed(const Name& prefix, const std::string& reason);
120
121private: // single data fetching
122 /**
123 * @brief fetch one data
124 */
125 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800126 onData(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700127
Shuo Chenc88c87d2014-06-25 20:21:02 +0800128 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700129 onDataValidated(const Interest& interest, const std::shared_ptr<const Data>& data,
Shuo Chenc88c87d2014-06-25 20:21:02 +0800130 ProcessId processId);
131
Shuo Chen29c77fe2014-03-18 11:29:41 -0700132 /**
133 * @brief handle when fetching one data timeout
134 */
135 void
136 onTimeout(const Interest& interest, ProcessId processId);
137
138 void
139 processSingleInsertCommand(const Interest& interest, RepoCommandParameter& parameter);
140
141private: // segmented data fetching
142 /**
143 * @brief fetch segmented data
144 */
145 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800146 onSegmentData(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700147
Shuo Chenc88c87d2014-06-25 20:21:02 +0800148 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700149 onSegmentDataValidated(const Interest& interest, const std::shared_ptr<const Data>& data,
Shuo Chenc88c87d2014-06-25 20:21:02 +0800150 ProcessId processId);
151
Shuo Chen29c77fe2014-03-18 11:29:41 -0700152 /**
153 * @brief Timeout when fetching segmented data. Data can be fetched RETRY_TIMEOUT times.
154 */
155 void
156 onSegmentTimeout(const Interest& interest, ProcessId processId);
157
158 /**
159 * @brief initiate fetching segmented data
160 */
161 void
162 segInit(ProcessId processId, const RepoCommandParameter& parameter);
163
164 /**
165 * @brief control for sending interests in function onSegmentData()
166 */
167 void
168 onSegmentDataControl(ProcessId processId, const Interest& interest);
169
170 /**
171 * @brief control for sending interest in function onSegmentTimeout
172 */
173 void
174 onSegmentTimeoutControl(ProcessId processId, const Interest& interest);
175
176 void
177 processSegmentedInsertCommand(const Interest& interest, RepoCommandParameter& parameter);
178
Shuo Chenc88c87d2014-06-25 20:21:02 +0800179private:
180 /**
181 * @brief failure of validation for both one or segmented data
182 */
183 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700184 onDataValidationFailed(const std::shared_ptr<const Data>& data, const std::string& reason);
Shuo Chenc88c87d2014-06-25 20:21:02 +0800185
Shuo Chen29c77fe2014-03-18 11:29:41 -0700186 /**
187 * @brief extends noEndTime of process if not noEndTimeout, set StatusCode 405
188 *
189 * called by onCheckValidated() if there is no EndBlockId. If not noEndTimeout,
190 * extends noEndTime of process. If noEndTimeout, set status code 405 as noEndTimeout.
191 */
192 void
193 extendNoEndTime(ProcessInfo& process);
194
195private: // insert state check command
196 /**
197 * @brief handle insert check command
198 */
199 void
200 onCheckInterest(const Name& prefix, const Interest& interest);
201
202 /**
203 * @brief insert check command prefix register failed
204 */
205 void
206 onCheckRegisterFailed(const Name& prefix, const std::string& reason);
207
208 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700209 onCheckValidated(const std::shared_ptr<const Interest>& interest, const Name& prefix);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700210
211 void
Wentao Shanga8f3c402014-10-30 14:03:27 -0700212 onCheckValidationFailed(const std::shared_ptr<const Interest>& interest,
213 const std::string& reason);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700214
215private:
216 void
217 deleteProcess(ProcessId processId);
218
219 /**
220 * @brief schedule a event to delete the process
221 */
222 void
223 deferredDeleteProcess(ProcessId processId);
224
225 void
226 negativeReply(const Interest& interest, int statusCode);
227
228private:
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000229 Validator& m_validator;
Shuo Chen29c77fe2014-03-18 11:29:41 -0700230
231 map<ProcessId, ProcessInfo> m_processes;
232
233 int m_retryTime;
234 int m_credit;
235 ndn::time::milliseconds m_noEndTimeout;
Weiqi Shi098f91c2014-07-23 17:41:35 -0700236 ndn::time::milliseconds m_interestLifetime;
Shuo Chen29c77fe2014-03-18 11:29:41 -0700237};
238
239} // namespace repo
240
Alexander Afanasyev39d98072014-05-04 12:46:29 -0700241#endif // REPO_HANDLES_WRITE_HANDLE_HPP