blob: 686d68c9201ec0d1b10344f9ece8b49bd15be283 [file] [log] [blame]
Shuo Chen29c77fe2014-03-18 11:29:41 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevc0e26582017-08-13 21:16:49 -04002/*
weijia yuan82cf9142018-10-21 12:25:02 -07003 * Copyright (c) 2014-2018, 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
weijia yuan82cf9142018-10-21 12:25:02 -070023#include "command-base-handle.hpp"
24
25#include <ndn-cxx/mgmt/dispatcher.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 */
weijia yuan82cf9142018-10-21 12:25:02 -070056class WriteHandle : public CommandBaseHandle
Shuo Chen29c77fe2014-03-18 11:29:41 -070057{
58
59public:
weijia yuan82cf9142018-10-21 12:25:02 -070060 class Error : public CommandBaseHandle::Error
Shuo Chen29c77fe2014-03-18 11:29:41 -070061 {
62 public:
63 explicit
64 Error(const std::string& what)
weijia yuan82cf9142018-10-21 12:25:02 -070065 : CommandBaseHandle::Error(what)
Shuo Chen29c77fe2014-03-18 11:29:41 -070066 {
67 }
68 };
69
70
71public:
weijia yuan82cf9142018-10-21 12:25:02 -070072 WriteHandle(Face& face, RepoStorage& storageHandle,
73 ndn::mgmt::Dispatcher& dispatcher, Scheduler& scheduler,
74 Validator& validator);
Shuo Chen29c77fe2014-03-18 11:29:41 -070075
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
weijia yuan82cf9142018-10-21 12:25:02 -0700107 handleInsertCommand(const Name& prefix, const Interest& interest,
108 const ndn::mgmt::ControlParameters& parameters,
109 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700110
111 void
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400112 onValidationFailed(const Interest& interest, const ValidationError& error);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700113
Shuo Chen29c77fe2014-03-18 11:29:41 -0700114private: // single data fetching
115 /**
116 * @brief fetch one data
117 */
118 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800119 onData(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700120
Shuo Chenc88c87d2014-06-25 20:21:02 +0800121 void
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400122 onDataValidated(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chenc88c87d2014-06-25 20:21:02 +0800123
Shuo Chen29c77fe2014-03-18 11:29:41 -0700124 /**
125 * @brief handle when fetching one data timeout
126 */
127 void
128 onTimeout(const Interest& interest, ProcessId processId);
129
130 void
weijia yuan82cf9142018-10-21 12:25:02 -0700131 processSingleInsertCommand(const Interest& interest, RepoCommandParameter& parameter,
132 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700133
134private: // segmented data fetching
135 /**
136 * @brief fetch segmented data
137 */
138 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800139 onSegmentData(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700140
Shuo Chenc88c87d2014-06-25 20:21:02 +0800141 void
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400142 onSegmentDataValidated(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chenc88c87d2014-06-25 20:21:02 +0800143
Shuo Chen29c77fe2014-03-18 11:29:41 -0700144 /**
145 * @brief Timeout when fetching segmented data. Data can be fetched RETRY_TIMEOUT times.
146 */
147 void
148 onSegmentTimeout(const Interest& interest, ProcessId processId);
149
150 /**
151 * @brief initiate fetching segmented data
152 */
153 void
154 segInit(ProcessId processId, const RepoCommandParameter& parameter);
155
156 /**
157 * @brief control for sending interests in function onSegmentData()
158 */
159 void
160 onSegmentDataControl(ProcessId processId, const Interest& interest);
161
162 /**
163 * @brief control for sending interest in function onSegmentTimeout
164 */
165 void
166 onSegmentTimeoutControl(ProcessId processId, const Interest& interest);
167
168 void
weijia yuan82cf9142018-10-21 12:25:02 -0700169 processSegmentedInsertCommand(const Interest& interest, RepoCommandParameter& parameter,
170 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700171
Shuo Chenc88c87d2014-06-25 20:21:02 +0800172private:
173 /**
174 * @brief failure of validation for both one or segmented data
175 */
176 void
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400177 onDataValidationFailed(const Data& data, const ValidationError& error);
Shuo Chenc88c87d2014-06-25 20:21:02 +0800178
Shuo Chen29c77fe2014-03-18 11:29:41 -0700179 /**
180 * @brief extends noEndTime of process if not noEndTimeout, set StatusCode 405
181 *
182 * called by onCheckValidated() if there is no EndBlockId. If not noEndTimeout,
183 * extends noEndTime of process. If noEndTimeout, set status code 405 as noEndTimeout.
184 */
185 void
186 extendNoEndTime(ProcessInfo& process);
187
188private: // insert state check command
189 /**
190 * @brief handle insert check command
191 */
Shuo Chen29c77fe2014-03-18 11:29:41 -0700192
Shuo Chen29c77fe2014-03-18 11:29:41 -0700193 void
weijia yuan82cf9142018-10-21 12:25:02 -0700194 handleCheckCommand(const Name& prefix, const Interest& interest,
195 const ndn::mgmt::ControlParameters& parameters,
196 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700197
198 void
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400199 onCheckValidationFailed(const Interest& interest, const ValidationError& error);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700200
201private:
202 void
203 deleteProcess(ProcessId processId);
204
205 /**
206 * @brief schedule a event to delete the process
207 */
208 void
209 deferredDeleteProcess(ProcessId processId);
210
weijia yuan82cf9142018-10-21 12:25:02 -0700211 RepoCommandResponse
212 negativeReply(std::string text, int statusCode);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700213
214private:
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000215 Validator& m_validator;
Shuo Chen29c77fe2014-03-18 11:29:41 -0700216 map<ProcessId, ProcessInfo> m_processes;
Shuo Chen29c77fe2014-03-18 11:29:41 -0700217 int m_retryTime;
218 int m_credit;
219 ndn::time::milliseconds m_noEndTimeout;
Weiqi Shi098f91c2014-07-23 17:41:35 -0700220 ndn::time::milliseconds m_interestLifetime;
Shuo Chen29c77fe2014-03-18 11:29:41 -0700221};
222
223} // namespace repo
224
Alexander Afanasyev39d98072014-05-04 12:46:29 -0700225#endif // REPO_HANDLES_WRITE_HANDLE_HPP