blob: 45d67182af8bb25834f7fc6b37a398689a547cdd [file] [log] [blame]
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Lijing Wang8e56d082016-12-25 14:45:23 -08003 * Copyright (c) 2013-2017, Regents of the University of California.
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -08004 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08005 * This file is part of ChronoShare, a decentralized file sharing application over NDN.
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -08006 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08007 * ChronoShare is free software: you can redistribute it and/or modify it under the terms
8 * of the GNU General Public License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080010 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -080011 * ChronoShare is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080014 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -080015 * You should have received copies of the GNU General Public License along with
16 * ChronoShare, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * See AUTHORS.md for complete list of ChronoShare authors and contributors.
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080019 */
20
Lijing Wang8e56d082016-12-25 14:45:23 -080021#ifndef CHRONOSHARE_SRC_DISPATCHER_HPP
22#define CHRONOSHARE_SRC_DISPATCHER_HPP
23
24#include "core/chronoshare-common.hpp"
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080025
Alexander Afanasyevf4cde4e2016-12-25 13:42:57 -080026#include "action-log.hpp"
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080027#include "content-server.hpp"
Lijing Wangb95c6a52016-12-25 14:45:17 -080028#include "state-server.hpp"
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080029#include "fetch-manager.hpp"
Alexander Afanasyevf4cde4e2016-12-25 13:42:57 -080030#include "object-db.hpp"
31#include "object-manager.hpp"
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080032#include "sync-core.hpp"
Alexander Afanasyevf9978f82013-01-23 16:30:31 -080033
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080034#include <boost/filesystem.hpp>
Lijing Wang8e56d082016-12-25 14:45:23 -080035#include <boost/filesystem/fstream.hpp>
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080036#include <map>
37
Lijing Wang8e56d082016-12-25 14:45:23 -080038namespace ndn {
39namespace chronoshare {
40
41typedef shared_ptr<ActionItem> ActionItemPtr;
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080042
43// TODO:
44// This class lacks a permanent table to store the files in fetching process
45// and fetch the missing pieces for those in the table after the application launches
Lijing Wang8e56d082016-12-25 14:45:23 -080046
47/**
48 * @brief Class synchroize different components
49 *
50 * - from SyncLog: when state changes -> to fetch missing actions
51 *
52 * - from FetchManager/Actions: when action is fetched -> to request a file, specified by the action
53 * -> to add action to the action log
54 *
55 * - from ActionLog/Delete: when action applied(file state changed, file deleted) -> to delete local file
56 *
57 * - from ActionLog/AddOrUpdate: when action applied(file state changes, file added or modified) ->
58 * to assemble the file if file is available in the ObjectDb, otherwise, do nothing
59 *
60 * - from FetchManager/Files: when file segment is retrieved -> save it in ObjectDb
61 * when file fetch is completed -> if file belongs to FileState, then assemble
62 * it to filesystem. Don't do anything otherwise
63 */
64
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080065class Dispatcher
66{
67public:
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080068 // sharedFolder is the name to be used in NDN name;
69 // rootDir is the shared folder dir in local file system;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080070 Dispatcher(const std::string& localUserName, const std::string& sharedFolder,
Lijing Wang8e56d082016-12-25 14:45:23 -080071 const boost::filesystem::path& rootDir, Face& face, bool enablePrefixDiscovery = true);
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080072 ~Dispatcher();
73
Lijing Wang8e56d082016-12-25 14:45:23 -080074 // ----- Callbacks, they only submit the job to executor and immediately return so that event
75 // processing thread won't be blocked for too long -------
Alexander Afanasyevf9978f82013-01-23 16:30:31 -080076
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080077 // callback to process local file change
78 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080079 Did_LocalFile_AddOrModify(const boost::filesystem::path& relativeFilepath);
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080080
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080081 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080082 Did_LocalFile_Delete(const boost::filesystem::path& relativeFilepath);
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -080083
Alexander Afanasyev0a30a0c2013-01-29 17:25:42 -080084 /**
85 * @brief Invoked when FileState is detected to have a file which does not exist on a file system
86 */
87 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080088 Restore_LocalFile(FileItemPtr file);
Alexander Afanasyev0a30a0c2013-01-29 17:25:42 -080089
Zhenkai Zhufaee2d42013-01-24 17:47:13 -080090 // for test
Lijing Wang8e56d082016-12-25 14:45:23 -080091 ConstBufferPtr
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080092 SyncRoot()
93 {
94 return m_core->root();
95 }
Zhenkai Zhufaee2d42013-01-24 17:47:13 -080096
Zhenkai Zhu25e13582013-02-27 15:33:01 -080097 inline void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080098 LookupRecentFileActions(const boost::function<void(const std::string&, int, int)>& visitor,
99 int limit)
100 {
101 m_actionLog->LookupRecentFileActions(visitor, limit);
102 }
Zhenkai Zhu25e13582013-02-27 15:33:01 -0800103
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800104private:
105 void
Lijing Wang8e56d082016-12-25 14:45:23 -0800106 Did_LocalFile_AddOrModify_Execute(boost::filesystem::path relativeFilepath); // cannot be const &
107 // for Execute
108 // event!!! otherwise
109 // there will be
110 // segfault
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800111
112 void
Lijing Wang8e56d082016-12-25 14:45:23 -0800113 Did_LocalFile_Delete_Execute(boost::filesystem::path relativeFilepath); // cannot be const & for
114 // Execute event!!!
115 // otherwise there will be
116 // segfault
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800117
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800118 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800119 Restore_LocalFile_Execute(FileItemPtr file);
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800120
121private:
122 /**
123 * Callbacks:
124 *
Lijing Wang8e56d082016-12-25 14:45:23 -0800125 * - from SyncLog: when state changes -> to fetch missing actions
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800126 *
Lijing Wang8e56d082016-12-25 14:45:23 -0800127 * - from FetchManager/Actions: when action is fetched -> to request a file, specified by the action
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800128 * -> to add action to the action log
129 *
Lijing Wang8e56d082016-12-25 14:45:23 -0800130 * - from ActionLog/Delete: when action applied(file state changed, file deleted) -> to delete local file
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800131 *
Lijing Wang8e56d082016-12-25 14:45:23 -0800132 * - from ActionLog/AddOrUpdate: when action applied(file state changes, file added or modified) ->
133 * to assemble the file if file is available in the ObjectDb, otherwise, do nothing
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800134 *
Lijing Wang8e56d082016-12-25 14:45:23 -0800135 * - from FetchManager/Files: when file segment is retrieved -> save it in ObjectDb
136 * when file fetch is completed -> if file belongs to FileState, then assemble
137 * it to filesystem. Don't do anything otherwise
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800138 */
139
140 // callback to process remote sync state change
141 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800142 Did_SyncLog_StateChange(SyncStateMsgPtr stateMsg);
Alexander Afanasyevfc720362013-01-24 21:49:48 -0800143
144 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800145 Did_SyncLog_StateChange_Execute(SyncStateMsgPtr stateMsg);
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800146
147 void
Lijing Wang8e56d082016-12-25 14:45:23 -0800148 Did_FetchManager_ActionFetch(const Name& deviceName, const Name& actionName, uint32_t seqno,
149 shared_ptr<Data> actionData);
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800150
151 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800152 Did_ActionLog_ActionApply_Delete(const std::string& filename);
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800153
154 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800155 Did_ActionLog_ActionApply_Delete_Execute(std::string filename);
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800156
157 // void
Lijing Wang8e56d082016-12-25 14:45:23 -0800158 // Did_ActionLog_ActionApply_AddOrModify(const std::string &filename, Name device_name,
159 // sqlite3_int64 seq_no,
160 // ConstBufferPtr hash, time_t m_time, int mode, int
161 // seg_num);
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800162
163 void
Lijing Wang8e56d082016-12-25 14:45:23 -0800164 Did_FetchManager_FileSegmentFetch(const Name& deviceName, const Name& fileSegmentName,
165 uint32_t segment, shared_ptr<Data> fileSegmentData);
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800166
167 void
Lijing Wang8e56d082016-12-25 14:45:23 -0800168 Did_FetchManager_FileSegmentFetch_Execute(Name deviceName, Name fileSegmentName, uint32_t segment,
169 shared_ptr<Data> fileSegmentData);
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800170
171 void
Lijing Wang8e56d082016-12-25 14:45:23 -0800172 Did_FetchManager_FileFetchComplete(const Name& deviceName, const Name& fileBaseName);
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800173
174 void
Lijing Wang8e56d082016-12-25 14:45:23 -0800175 Did_FetchManager_FileFetchComplete_Execute(Name deviceName, Name fileBaseName);
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800176
Alexander Afanasyev758f51b2013-01-24 13:48:18 -0800177 void
Lijing Wang8e56d082016-12-25 14:45:23 -0800178 Did_LocalPrefix_Updated(const Name& prefix);
Alexander Afanasyev758f51b2013-01-24 13:48:18 -0800179
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800180private:
181 void
Lijing Wang8e56d082016-12-25 14:45:23 -0800182 AssembleFile_Execute(const Name& deviceName, const Buffer& filehash,
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800183 const boost::filesystem::path& relativeFilepath);
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800184
185 // void
186 // fileChanged(const boost::filesystem::path &relativeFilepath, ActionType type);
187
188 // void
189 // syncStateChanged(const SyncStateMsgPtr &stateMsg);
190
191 // void
192 // actionReceived(const ActionItemPtr &actionItem);
193
194 // void
Lijing Wang8e56d082016-12-25 14:45:23 -0800195 // fileSegmentReceived(const Name &name, const Ccnx::Bytes &content);
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800196
197 // void
Lijing Wang8e56d082016-12-25 14:45:23 -0800198 // fileReady(const Name &fileNamePrefix);
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800199
200private:
Lijing Wang8e56d082016-12-25 14:45:23 -0800201 Face& m_face;
202 unique_ptr<SyncCore> m_core;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800203 SyncLogPtr m_syncLog;
Alexander Afanasyevcbda9922013-01-22 11:21:12 -0800204 ActionLogPtr m_actionLog;
Alexander Afanasyevd6364ef2013-02-06 13:13:07 -0800205 FileStatePtr m_fileState;
Yingdi Yuadb54eb2013-08-15 10:28:28 -0700206 FileStatePtr m_fileStateCow;
Alexander Afanasyevcbda9922013-01-22 11:21:12 -0800207
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800208 boost::filesystem::path m_rootDir;
Lijing Wang8e56d082016-12-25 14:45:23 -0800209 boost::asio::io_service& m_ioService;
210
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800211 ObjectManager m_objectManager;
Lijing Wang8e56d082016-12-25 14:45:23 -0800212 Name m_localUserName;
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800213 // maintain object db ptrs so that we don't need to create them
214 // for every fetched segment of a file
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800215
Lijing Wang8e56d082016-12-25 14:45:23 -0800216 std::map<Buffer, shared_ptr<ObjectDb>> m_objectDbMap;
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800217
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800218 std::string m_sharedFolder;
Lijing Wang8e56d082016-12-25 14:45:23 -0800219 unique_ptr<ContentServer> m_server;
Lijing Wangb95c6a52016-12-25 14:45:17 -0800220 unique_ptr<StateServer> m_stateServer;
Zhenkai Zhufaee2d42013-01-24 17:47:13 -0800221 bool m_enablePrefixDiscovery;
Alexander Afanasyevf9978f82013-01-23 16:30:31 -0800222
223 FetchManagerPtr m_actionFetcher;
224 FetchManagerPtr m_fileFetcher;
Lijing Wang8e56d082016-12-25 14:45:23 -0800225
226 KeyChain m_keyChain;
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800227};
228
Lijing Wang8e56d082016-12-25 14:45:23 -0800229namespace error {
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800230struct Dispatcher : virtual boost::exception, virtual std::exception
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800231{
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800232};
233typedef boost::error_info<struct tag_errmsg, std::string> error_info_str;
Lijing Wang8e56d082016-12-25 14:45:23 -0800234} // namespace error
Zhenkai Zhuc3fd51e2013-01-22 10:45:54 -0800235
Lijing Wang8e56d082016-12-25 14:45:23 -0800236} // namespace chronoshare
237} // namespace ndn
238
239#endif // CHRONOSHARE_SRC_DISPATCHER_HPP