blob: d74f21064b96cd6606cba308c617eac87fb88c78 [file] [log] [blame]
Alexander Afanasyev8811b352013-01-02 12:51:15 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 * Zhenkai Zhu <zhenkai@cs.ucla.edu>
20 */
21
Alexander Afanasyev49a18522013-01-18 17:49:04 -080022#include "fetch-manager.h"
23#include <boost/make_shared.hpp>
24#include <boost/ref.hpp>
25#include <boost/throw_exception.hpp>
Alexander Afanasyevfc720362013-01-24 21:49:48 -080026#include "logging.h"
27
Alexander Afanasyevff8d9dc2013-01-26 00:45:08 -080028INIT_LOGGER ("FetchManager");
Alexander Afanasyev49a18522013-01-18 17:49:04 -080029
30using namespace boost;
31using namespace std;
32using namespace Ccnx;
33
Zhenkai Zhu3f64d2d2013-01-25 14:34:59 -080034static const string BROADCAST_DOMAIN = "/ndn/broadcast/chronoshare";
Alexander Afanasyev83531a42013-01-19 16:21:54 -080035//The disposer object function
36struct fetcher_disposer { void operator() (Fetcher *delete_this) { delete delete_this; } };
37
Alexander Afanasyevf9978f82013-01-23 16:30:31 -080038FetchManager::FetchManager (CcnxWrapperPtr ccnx, const Mapping &mapping, uint32_t parallelFetches/* = 3*/)
Alexander Afanasyev49a18522013-01-18 17:49:04 -080039 : m_ccnx (ccnx)
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -080040 , m_mapping (mapping)
Alexander Afanasyev83531a42013-01-19 16:21:54 -080041 , m_maxParallelFetches (parallelFetches)
42 , m_currentParallelFetches (0)
43
Alexander Afanasyev8811b352013-01-02 12:51:15 -080044{
Alexander Afanasyev49a18522013-01-18 17:49:04 -080045}
Alexander Afanasyeva199f972013-01-02 19:37:26 -080046
Alexander Afanasyev49a18522013-01-18 17:49:04 -080047FetchManager::~FetchManager ()
48{
Alexander Afanasyev83531a42013-01-19 16:21:54 -080049 m_fetchList.clear_and_dispose (fetcher_disposer ());
Alexander Afanasyev49a18522013-01-18 17:49:04 -080050}
Alexander Afanasyev8811b352013-01-02 12:51:15 -080051
Alexander Afanasyev49a18522013-01-18 17:49:04 -080052void
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -080053FetchManager::Enqueue (const Ccnx::Name &deviceName, const Ccnx::Name &baseName,
54 const SegmentCallback &segmentCallback, const FinishCallback &finishCallback,
55 uint64_t minSeqNo, uint64_t maxSeqNo, int priority/*PRIORITY_NORMAL*/)
Alexander Afanasyev49a18522013-01-18 17:49:04 -080056{
Zhenkai Zhu454bae22013-01-24 19:27:54 -080057 // Assumption for the following code is minSeqNo <= maxSeqNo
58 if (minSeqNo > maxSeqNo)
59 {
60 return;
61 }
62
Alexander Afanasyev83531a42013-01-19 16:21:54 -080063 // we may need to guarantee that LookupLocator will gives an answer and not throw exception...
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080064 Name forwardingHint;
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -080065 forwardingHint = m_mapping (deviceName);
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080066
67 Fetcher &fetcher = *(new Fetcher (m_ccnx,
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -080068 segmentCallback,
69 finishCallback,
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080070 bind (&FetchManager::DidFetchComplete, this, _1),
71 bind (&FetchManager::DidNoDataTimeout, this, _1),
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -080072 deviceName, baseName, minSeqNo, maxSeqNo,
73 boost::posix_time::seconds (30),
74 forwardingHint));
Alexander Afanasyev83531a42013-01-19 16:21:54 -080075
76 switch (priority)
77 {
78 case PRIORITY_HIGH:
79 m_fetchList.push_front (fetcher);
80 break;
81
82 case PRIORITY_NORMAL:
83 default:
84 m_fetchList.push_back (fetcher);
85 break;
86 }
87
88 ScheduleFetches (); // will start a fetch if m_currentParallelFetches is less than max, otherwise does nothing
Alexander Afanasyev49a18522013-01-18 17:49:04 -080089}
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -080090
Alexander Afanasyev83531a42013-01-19 16:21:54 -080091void
92FetchManager::ScheduleFetches ()
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -080093{
Alexander Afanasyev83531a42013-01-19 16:21:54 -080094 unique_lock<mutex> lock (m_parellelFetchMutex);
95
96 for (FetchList::iterator item = m_fetchList.begin ();
97 m_currentParallelFetches < m_maxParallelFetches && item != m_fetchList.end ();
98 item++)
99 {
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800100 if (item->IsActive ())
Alexander Afanasyev83531a42013-01-19 16:21:54 -0800101 continue;
102
Alexander Afanasyevff8d9dc2013-01-26 00:45:08 -0800103 _LOG_DEBUG ("Start fetching of " << item->GetName ());
104
Alexander Afanasyev83531a42013-01-19 16:21:54 -0800105 m_currentParallelFetches ++;
106 item->RestartPipeline ();
107 }
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -0800108}
109
Alexander Afanasyev83531a42013-01-19 16:21:54 -0800110void
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800111FetchManager::DidNoDataTimeout (Fetcher &fetcher)
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -0800112{
Alexander Afanasyevff8d9dc2013-01-26 00:45:08 -0800113 _LOG_DEBUG ("No data timeout for " << fetcher.GetName () << " with forwarding hint: " << fetcher.GetForwardingHint ());
114
Zhenkai Zhu3f64d2d2013-01-25 14:34:59 -0800115 fetcher.SetForwardingHint (Ccnx::Name (BROADCAST_DOMAIN));
Alexander Afanasyev83531a42013-01-19 16:21:54 -0800116 {
117 unique_lock<mutex> lock (m_parellelFetchMutex);
118 m_currentParallelFetches --;
119 // no need to do anything with the m_fetchList
120 }
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800121
Alexander Afanasyev83531a42013-01-19 16:21:54 -0800122 ScheduleFetches ();
123}
124
125void
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800126FetchManager::DidFetchComplete (Fetcher &fetcher)
Alexander Afanasyev83531a42013-01-19 16:21:54 -0800127{
Alexander Afanasyev83531a42013-01-19 16:21:54 -0800128 {
129 unique_lock<mutex> lock (m_parellelFetchMutex);
130 m_currentParallelFetches --;
131 m_fetchList.erase_and_dispose (FetchList::s_iterator_to (fetcher), fetcher_disposer ());
132 }
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800133
Alexander Afanasyeve41e7d22013-01-19 15:13:47 -0800134}