| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| /** |
| * Copyright (c) 2013-2017, Regents of the University of California. |
| * |
| * This file is part of ChronoShare, a decentralized file sharing application over NDN. |
| * |
| * ChronoShare is free software: you can redistribute it and/or modify it under the terms |
| * of the GNU General Public License as published by the Free Software Foundation, either |
| * version 3 of the License, or (at your option) any later version. |
| * |
| * ChronoShare is distributed in the hope that it will be useful, but WITHOUT ANY |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
| * PARTICULAR PURPOSE. See the GNU General Public License for more details. |
| * |
| * You should have received copies of the GNU General Public License along with |
| * ChronoShare, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>. |
| * |
| * See AUTHORS.md for complete list of ChronoShare authors and contributors. |
| */ |
| |
| #ifndef CHRONOSHARE_SRC_DISPATCHER_HPP |
| #define CHRONOSHARE_SRC_DISPATCHER_HPP |
| |
| #include "core/chronoshare-common.hpp" |
| |
| #include "action-log.hpp" |
| #include "content-server.hpp" |
| #include "state-server.hpp" |
| #include "fetch-manager.hpp" |
| #include "object-db.hpp" |
| #include "object-manager.hpp" |
| #include "sync-core.hpp" |
| |
| #include <boost/filesystem.hpp> |
| #include <boost/filesystem/fstream.hpp> |
| #include <map> |
| |
| namespace ndn { |
| namespace chronoshare { |
| |
| typedef shared_ptr<ActionItem> ActionItemPtr; |
| |
| // TODO: |
| // This class lacks a permanent table to store the files in fetching process |
| // and fetch the missing pieces for those in the table after the application launches |
| |
| /** |
| * @brief Class synchroize different components |
| * |
| * - from SyncLog: when state changes -> to fetch missing actions |
| * |
| * - from FetchManager/Actions: when action is fetched -> to request a file, specified by the action |
| * -> to add action to the action log |
| * |
| * - from ActionLog/Delete: when action applied(file state changed, file deleted) -> to delete local file |
| * |
| * - from ActionLog/AddOrUpdate: when action applied(file state changes, file added or modified) -> |
| * to assemble the file if file is available in the ObjectDb, otherwise, do nothing |
| * |
| * - from FetchManager/Files: when file segment is retrieved -> save it in ObjectDb |
| * when file fetch is completed -> if file belongs to FileState, then assemble |
| * it to filesystem. Don't do anything otherwise |
| */ |
| |
| class Dispatcher |
| { |
| public: |
| // sharedFolder is the name to be used in NDN name; |
| // rootDir is the shared folder dir in local file system; |
| Dispatcher(const std::string& localUserName, const std::string& sharedFolder, |
| const boost::filesystem::path& rootDir, Face& face); |
| ~Dispatcher(); |
| |
| // ----- Callbacks, they only submit the job to executor and immediately return so that event |
| // processing thread won't be blocked for too long ------- |
| |
| // callback to process local file change |
| void |
| Did_LocalFile_AddOrModify(const boost::filesystem::path& relativeFilepath); |
| |
| void |
| Did_LocalFile_Delete(const boost::filesystem::path& relativeFilepath); |
| |
| /** |
| * @brief Invoked when FileState is detected to have a file which does not exist on a file system |
| */ |
| void |
| Restore_LocalFile(FileItemPtr file); |
| |
| // for test |
| ConstBufferPtr |
| SyncRoot() |
| { |
| return m_core->root(); |
| } |
| |
| inline void |
| LookupRecentFileActions(const boost::function<void(const std::string&, int, int)>& visitor, |
| int limit) |
| { |
| m_actionLog->LookupRecentFileActions(visitor, limit); |
| } |
| |
| private: |
| void |
| Did_LocalFile_AddOrModify_Execute(boost::filesystem::path relativeFilepath); // cannot be const & |
| // for Execute |
| // event!!! otherwise |
| // there will be |
| // segfault |
| |
| void |
| Did_LocalFile_Delete_Execute(boost::filesystem::path relativeFilepath); // cannot be const & for |
| // Execute event!!! |
| // otherwise there will be |
| // segfault |
| |
| void |
| Restore_LocalFile_Execute(FileItemPtr file); |
| |
| private: |
| /** |
| * Callbacks: |
| * |
| * - from SyncLog: when state changes -> to fetch missing actions |
| * |
| * - from FetchManager/Actions: when action is fetched -> to request a file, specified by the action |
| * -> to add action to the action log |
| * |
| * - from ActionLog/Delete: when action applied(file state changed, file deleted) -> to delete local file |
| * |
| * - from ActionLog/AddOrUpdate: when action applied(file state changes, file added or modified) -> |
| * to assemble the file if file is available in the ObjectDb, otherwise, do nothing |
| * |
| * - from FetchManager/Files: when file segment is retrieved -> save it in ObjectDb |
| * when file fetch is completed -> if file belongs to FileState, then assemble |
| * it to filesystem. Don't do anything otherwise |
| */ |
| |
| // callback to process remote sync state change |
| void |
| Did_SyncLog_StateChange(SyncStateMsgPtr stateMsg); |
| |
| void |
| Did_SyncLog_StateChange_Execute(SyncStateMsgPtr stateMsg); |
| |
| void |
| Did_FetchManager_ActionFetch(const Name& deviceName, const Name& actionName, uint32_t seqno, |
| shared_ptr<Data> actionData); |
| |
| void |
| Did_ActionLog_ActionApply_Delete(const std::string& filename); |
| |
| void |
| Did_ActionLog_ActionApply_Delete_Execute(std::string filename); |
| |
| void |
| Did_FetchManager_FileSegmentFetch(const Name& deviceName, const Name& fileSegmentName, |
| uint32_t segment, shared_ptr<Data> fileSegmentData); |
| |
| void |
| Did_FetchManager_FileSegmentFetch_Execute(Name deviceName, Name fileSegmentName, uint32_t segment, |
| shared_ptr<Data> fileSegmentData); |
| |
| void |
| Did_FetchManager_FileFetchComplete(const Name& deviceName, const Name& fileBaseName); |
| |
| void |
| Did_FetchManager_FileFetchComplete_Execute(Name deviceName, Name fileBaseName); |
| |
| void |
| Handle_Prefix_Discovery(const Interest& interest, const Data& data); |
| |
| void |
| DiscoverPrefix(); |
| |
| void |
| Did_LocalPrefix_Updated(const Name& prefix); |
| |
| private: |
| void |
| AssembleFile_Execute(const Name& deviceName, const Buffer& filehash, |
| const boost::filesystem::path& relativeFilepath); |
| |
| private: |
| Face& m_face; |
| unique_ptr<SyncCore> m_core; |
| SyncLogPtr m_syncLog; |
| ActionLogPtr m_actionLog; |
| FileStatePtr m_fileState; |
| FileStatePtr m_fileStateCow; |
| |
| boost::filesystem::path m_rootDir; |
| boost::asio::io_service& m_ioService; |
| Scheduler m_scheduler; |
| util::scheduler::ScopedEventId m_autoDiscovery; |
| |
| ObjectManager m_objectManager; |
| Name m_localUserName; |
| // maintain object db ptrs so that we don't need to create them |
| // for every fetched segment of a file |
| |
| std::map<Buffer, shared_ptr<ObjectDb>> m_objectDbMap; |
| |
| std::string m_sharedFolder; |
| unique_ptr<ContentServer> m_server; |
| unique_ptr<StateServer> m_stateServer; |
| |
| FetchManagerPtr m_actionFetcher; |
| FetchManagerPtr m_fileFetcher; |
| |
| KeyChain m_keyChain; |
| }; |
| |
| namespace error { |
| struct Dispatcher : virtual boost::exception, virtual std::exception |
| { |
| }; |
| typedef boost::error_info<struct tag_errmsg, std::string> error_info_str; |
| } // namespace error |
| |
| } // namespace chronoshare |
| } // namespace ndn |
| |
| #endif // CHRONOSHARE_SRC_DISPATCHER_HPP |