blob: 115801edb98ecd36b8dc9f081d77e3c4c6d28ff4 [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>
weijia yuan3aa8d2b2018-03-06 15:35:57 -080026#include <ndn-cxx/util/segment-fetcher.hpp>
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -070027
Shuo Chen29c77fe2014-03-18 11:29:41 -070028#include <queue>
29
30namespace repo {
31
Shuo Chen29c77fe2014-03-18 11:29:41 -070032/**
Alexander Afanasyeve1e6f2a2014-04-25 11:28:12 -070033 * @brief WriteHandle provides basic credit based congestion control.
34 *
35 * First repo sends interests of credit number and then credit will be 0.
36 *
37 * If a data comes, credit++ and sends a interest then credit--.
38 *
39 * If the interest timeout, repo will retry and send interest in retrytimes.
40 *
41 * If one interest timeout beyond retrytimes, the fetching process will terminate.
42 *
43 * Another case is that if command will insert segmented data without EndBlockId.
44 *
45 * The repo will keep fetching data in noendTimeout time.
46 *
47 * If data returns with FinalBlockId, this detecting timeout process will terminate.
48 *
49 * If client sends a insert check command, the noendTimeout timer will be set to 0.
50 *
51 * If repo cannot get FinalBlockId in noendTimeout time, the fetching process will terminate.
52 */
weijia yuan82cf9142018-10-21 12:25:02 -070053class WriteHandle : public CommandBaseHandle
Shuo Chen29c77fe2014-03-18 11:29:41 -070054{
55
56public:
weijia yuan82cf9142018-10-21 12:25:02 -070057 class Error : public CommandBaseHandle::Error
Shuo Chen29c77fe2014-03-18 11:29:41 -070058 {
59 public:
60 explicit
61 Error(const std::string& what)
weijia yuan82cf9142018-10-21 12:25:02 -070062 : CommandBaseHandle::Error(what)
Shuo Chen29c77fe2014-03-18 11:29:41 -070063 {
64 }
65 };
66
67
68public:
weijia yuan82cf9142018-10-21 12:25:02 -070069 WriteHandle(Face& face, RepoStorage& storageHandle,
70 ndn::mgmt::Dispatcher& dispatcher, Scheduler& scheduler,
71 Validator& validator);
Shuo Chen29c77fe2014-03-18 11:29:41 -070072
73private:
74 /**
75 * @brief Information of insert process including variables for response
76 * and credit based flow control
77 */
78 struct ProcessInfo
79 {
Shuo Chen29c77fe2014-03-18 11:29:41 -070080 RepoCommandResponse response;
weijia yuan3aa8d2b2018-03-06 15:35:57 -080081 std::queue<SegmentNo> nextSegmentQueue; ///< queue of waiting segment
Shuo Chen29c77fe2014-03-18 11:29:41 -070082 /// to be sent when having credits
83 SegmentNo nextSegment; ///< last segment put into the nextSegmentQueue
weijia yuan3aa8d2b2018-03-06 15:35:57 -080084 std::map<SegmentNo, int> retryCounts; ///< to store retrying times of timeout segment
Shuo Chen29c77fe2014-03-18 11:29:41 -070085 int credit; ///< congestion control credits of process
86
87 /**
88 * @brief the latest time point at which EndBlockId must be determined
89 *
90 * Segmented fetch process will terminate if EndBlockId cannot be
91 * determined before this time point.
92 * It is initialized to now()+noEndTimeout when segmented fetch process begins,
93 * and reset to now()+noEndTimeout each time an insert status check command is processed.
94 */
95 ndn::time::steady_clock::TimePoint noEndTime;
96 };
97
98private: // insert command
99 /**
100 * @brief handle insert commands
101 */
102 void
weijia yuan82cf9142018-10-21 12:25:02 -0700103 handleInsertCommand(const Name& prefix, const Interest& interest,
104 const ndn::mgmt::ControlParameters& parameters,
105 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700106
107 void
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400108 onValidationFailed(const Interest& interest, const ValidationError& error);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700109
Shuo Chen29c77fe2014-03-18 11:29:41 -0700110private: // single data fetching
111 /**
112 * @brief fetch one data
113 */
114 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800115 onData(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700116
Shuo Chenc88c87d2014-06-25 20:21:02 +0800117 void
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400118 onDataValidated(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chenc88c87d2014-06-25 20:21:02 +0800119
Shuo Chen29c77fe2014-03-18 11:29:41 -0700120 /**
121 * @brief handle when fetching one data timeout
122 */
123 void
124 onTimeout(const Interest& interest, ProcessId processId);
125
126 void
weijia yuan82cf9142018-10-21 12:25:02 -0700127 processSingleInsertCommand(const Interest& interest, RepoCommandParameter& parameter,
128 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700129
130private: // segmented data fetching
131 /**
132 * @brief fetch segmented data
133 */
134 void
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800135 onSegmentData(ndn::util::SegmentFetcher& fetcher, const Data& data, ProcessId processId);
Shuo Chenc88c87d2014-06-25 20:21:02 +0800136
Shuo Chen29c77fe2014-03-18 11:29:41 -0700137 /**
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800138 * @brief handle when fetching segmented data timeout
Shuo Chen29c77fe2014-03-18 11:29:41 -0700139 */
140 void
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800141 onSegmentTimeout(ndn::util::SegmentFetcher& fetcher, ProcessId processId);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700142
143 /**
144 * @brief initiate fetching segmented data
145 */
146 void
147 segInit(ProcessId processId, const RepoCommandParameter& parameter);
148
Shuo Chen29c77fe2014-03-18 11:29:41 -0700149 void
weijia yuan82cf9142018-10-21 12:25:02 -0700150 processSegmentedInsertCommand(const Interest& interest, RepoCommandParameter& parameter,
151 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700152
Shuo Chenc88c87d2014-06-25 20:21:02 +0800153private:
154 /**
Shuo Chen29c77fe2014-03-18 11:29:41 -0700155 * @brief extends noEndTime of process if not noEndTimeout, set StatusCode 405
156 *
157 * called by onCheckValidated() if there is no EndBlockId. If not noEndTimeout,
158 * extends noEndTime of process. If noEndTimeout, set status code 405 as noEndTimeout.
159 */
160 void
161 extendNoEndTime(ProcessInfo& process);
162
163private: // insert state check command
164 /**
165 * @brief handle insert check command
166 */
Shuo Chen29c77fe2014-03-18 11:29:41 -0700167
Shuo Chen29c77fe2014-03-18 11:29:41 -0700168 void
weijia yuan82cf9142018-10-21 12:25:02 -0700169 handleCheckCommand(const Name& prefix, const Interest& interest,
170 const ndn::mgmt::ControlParameters& parameters,
171 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700172
173 void
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400174 onCheckValidationFailed(const Interest& interest, const ValidationError& error);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700175
176private:
177 void
178 deleteProcess(ProcessId processId);
179
180 /**
181 * @brief schedule a event to delete the process
182 */
183 void
184 deferredDeleteProcess(ProcessId processId);
185
weijia yuan82cf9142018-10-21 12:25:02 -0700186 RepoCommandResponse
187 negativeReply(std::string text, int statusCode);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700188
189private:
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000190 Validator& m_validator;
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800191
192 std::map<ProcessId, ProcessInfo> m_processes;
193
Shuo Chen29c77fe2014-03-18 11:29:41 -0700194 int m_credit;
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800195 bool m_canBePrefix;
196 ndn::time::milliseconds m_maxTimeout;
Shuo Chen29c77fe2014-03-18 11:29:41 -0700197 ndn::time::milliseconds m_noEndTimeout;
Weiqi Shi098f91c2014-07-23 17:41:35 -0700198 ndn::time::milliseconds m_interestLifetime;
Shuo Chen29c77fe2014-03-18 11:29:41 -0700199};
200
201} // namespace repo
202
Alexander Afanasyev39d98072014-05-04 12:46:29 -0700203#endif // REPO_HANDLES_WRITE_HANDLE_HPP