blob: 04ed3f5fe33e11407fa8f02871ff814e52a61165 [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/*
Davide Pesavento11904062022-04-14 22:33:28 -04003 * Copyright (c) 2014-2022, 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
weijia yuan3aa8d2b2018-03-06 15:35:57 -080025#include <ndn-cxx/util/segment-fetcher.hpp>
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -070026
Shuo Chen29c77fe2014-03-18 11:29:41 -070027#include <queue>
28
29namespace repo {
30
Shuo Chen29c77fe2014-03-18 11:29:41 -070031/**
Alexander Afanasyeve1e6f2a2014-04-25 11:28:12 -070032 * @brief WriteHandle provides basic credit based congestion control.
33 *
34 * First repo sends interests of credit number and then credit will be 0.
35 *
36 * If a data comes, credit++ and sends a interest then credit--.
37 *
38 * If the interest timeout, repo will retry and send interest in retrytimes.
39 *
40 * If one interest timeout beyond retrytimes, the fetching process will terminate.
41 *
42 * Another case is that if command will insert segmented data without EndBlockId.
43 *
44 * The repo will keep fetching data in noendTimeout time.
45 *
46 * If data returns with FinalBlockId, this detecting timeout process will terminate.
47 *
48 * If client sends a insert check command, the noendTimeout timer will be set to 0.
49 *
50 * If repo cannot get FinalBlockId in noendTimeout time, the fetching process will terminate.
51 */
weijia yuan82cf9142018-10-21 12:25:02 -070052class WriteHandle : public CommandBaseHandle
Shuo Chen29c77fe2014-03-18 11:29:41 -070053{
Shuo Chen29c77fe2014-03-18 11:29:41 -070054public:
weijia yuan82cf9142018-10-21 12:25:02 -070055 class Error : public CommandBaseHandle::Error
Shuo Chen29c77fe2014-03-18 11:29:41 -070056 {
57 public:
Davide Pesavento11904062022-04-14 22:33:28 -040058 using CommandBaseHandle::Error::Error;
Shuo Chen29c77fe2014-03-18 11:29:41 -070059 };
60
weijia yuan82cf9142018-10-21 12:25:02 -070061 WriteHandle(Face& face, RepoStorage& storageHandle,
62 ndn::mgmt::Dispatcher& dispatcher, Scheduler& scheduler,
Davide Pesavento11904062022-04-14 22:33:28 -040063 ndn::security::Validator& validator);
Shuo Chen29c77fe2014-03-18 11:29:41 -070064
65private:
66 /**
67 * @brief Information of insert process including variables for response
68 * and credit based flow control
69 */
70 struct ProcessInfo
71 {
Shuo Chen29c77fe2014-03-18 11:29:41 -070072 RepoCommandResponse response;
weijia yuan3aa8d2b2018-03-06 15:35:57 -080073 std::queue<SegmentNo> nextSegmentQueue; ///< queue of waiting segment
Shuo Chen29c77fe2014-03-18 11:29:41 -070074 /// to be sent when having credits
75 SegmentNo nextSegment; ///< last segment put into the nextSegmentQueue
weijia yuan3aa8d2b2018-03-06 15:35:57 -080076 std::map<SegmentNo, int> retryCounts; ///< to store retrying times of timeout segment
Shuo Chen29c77fe2014-03-18 11:29:41 -070077 int credit; ///< congestion control credits of process
78
79 /**
80 * @brief the latest time point at which EndBlockId must be determined
81 *
82 * Segmented fetch process will terminate if EndBlockId cannot be
83 * determined before this time point.
84 * It is initialized to now()+noEndTimeout when segmented fetch process begins,
85 * and reset to now()+noEndTimeout each time an insert status check command is processed.
86 */
Davide Pesavento11904062022-04-14 22:33:28 -040087 time::steady_clock::time_point noEndTime;
Shuo Chen29c77fe2014-03-18 11:29:41 -070088 };
89
90private: // insert command
91 /**
92 * @brief handle insert commands
93 */
94 void
weijia yuan82cf9142018-10-21 12:25:02 -070095 handleInsertCommand(const Name& prefix, const Interest& interest,
96 const ndn::mgmt::ControlParameters& parameters,
97 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -070098
99 void
Davide Pesavento11904062022-04-14 22:33:28 -0400100 onValidationFailed(const Interest& interest, const ndn::security::ValidationError& error);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700101
Shuo Chen29c77fe2014-03-18 11:29:41 -0700102private: // single data fetching
103 /**
104 * @brief fetch one data
105 */
106 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800107 onData(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700108
Shuo Chenc88c87d2014-06-25 20:21:02 +0800109 void
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400110 onDataValidated(const Interest& interest, const Data& data, ProcessId processId);
Shuo Chenc88c87d2014-06-25 20:21:02 +0800111
Shuo Chen29c77fe2014-03-18 11:29:41 -0700112 /**
113 * @brief handle when fetching one data timeout
114 */
115 void
116 onTimeout(const Interest& interest, ProcessId processId);
117
118 void
weijia yuan82cf9142018-10-21 12:25:02 -0700119 processSingleInsertCommand(const Interest& interest, RepoCommandParameter& parameter,
120 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700121
122private: // segmented data fetching
123 /**
124 * @brief fetch segmented data
125 */
126 void
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800127 onSegmentData(ndn::util::SegmentFetcher& fetcher, const Data& data, ProcessId processId);
Shuo Chenc88c87d2014-06-25 20:21:02 +0800128
Shuo Chen29c77fe2014-03-18 11:29:41 -0700129 /**
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800130 * @brief handle when fetching segmented data timeout
Shuo Chen29c77fe2014-03-18 11:29:41 -0700131 */
132 void
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800133 onSegmentTimeout(ndn::util::SegmentFetcher& fetcher, ProcessId processId);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700134
135 /**
136 * @brief initiate fetching segmented data
137 */
138 void
139 segInit(ProcessId processId, const RepoCommandParameter& parameter);
140
Shuo Chen29c77fe2014-03-18 11:29:41 -0700141 void
weijia yuan82cf9142018-10-21 12:25:02 -0700142 processSegmentedInsertCommand(const Interest& interest, RepoCommandParameter& parameter,
143 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700144
Shuo Chenc88c87d2014-06-25 20:21:02 +0800145private:
146 /**
Shuo Chen29c77fe2014-03-18 11:29:41 -0700147 * @brief extends noEndTime of process if not noEndTimeout, set StatusCode 405
148 *
149 * called by onCheckValidated() if there is no EndBlockId. If not noEndTimeout,
150 * extends noEndTime of process. If noEndTimeout, set status code 405 as noEndTimeout.
151 */
152 void
153 extendNoEndTime(ProcessInfo& process);
154
155private: // insert state check command
156 /**
157 * @brief handle insert check command
158 */
Shuo Chen29c77fe2014-03-18 11:29:41 -0700159
Shuo Chen29c77fe2014-03-18 11:29:41 -0700160 void
weijia yuan82cf9142018-10-21 12:25:02 -0700161 handleCheckCommand(const Name& prefix, const Interest& interest,
162 const ndn::mgmt::ControlParameters& parameters,
163 const ndn::mgmt::CommandContinuation& done);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700164
165 void
Davide Pesavento11904062022-04-14 22:33:28 -0400166 onCheckValidationFailed(const Interest& interest, const ndn::security::ValidationError& error);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700167
168private:
169 void
170 deleteProcess(ProcessId processId);
171
172 /**
173 * @brief schedule a event to delete the process
174 */
175 void
176 deferredDeleteProcess(ProcessId processId);
177
weijia yuan82cf9142018-10-21 12:25:02 -0700178 RepoCommandResponse
179 negativeReply(std::string text, int statusCode);
Shuo Chen29c77fe2014-03-18 11:29:41 -0700180
181private:
Davide Pesavento11904062022-04-14 22:33:28 -0400182 ndn::security::Validator& m_validator;
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800183 std::map<ProcessId, ProcessInfo> m_processes;
Davide Pesavento11904062022-04-14 22:33:28 -0400184 time::milliseconds m_interestLifetime = ndn::DEFAULT_INTEREST_LIFETIME;
Shuo Chen29c77fe2014-03-18 11:29:41 -0700185};
186
187} // namespace repo
188
Alexander Afanasyev39d98072014-05-04 12:46:29 -0700189#endif // REPO_HANDLES_WRITE_HANDLE_HPP