0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
RequestCache.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
28 #include "Common/Compat.h"
29 
30 #include <cassert>
31 
32 #define HT_DISABLE_LOG_DEBUG 1
33 
34 #include "Common/Logger.h"
35 
36 #include "IOHandlerData.h"
37 #include "RequestCache.h"
38 
39 using namespace Hypertable;
40 using namespace std;
41 
42 void
43 RequestCache::insert(uint32_t id, IOHandler *handler, DispatchHandler *dh,
44  ClockT::time_point &expire) {
45 
46  HT_DEBUGF("Adding id %d", id);
47 
48  IdHandlerMap::iterator iter = m_id_map.find(id);
49 
50  HT_ASSERT(iter == m_id_map.end());
51 
52  CacheNode *node = new CacheNode(id, handler, dh);
53  node->expire = expire;
54 
55  if (m_head == 0) {
56  node->next = node->prev = 0;
57  m_head = m_tail = node;
58  }
59  else {
60  node->next = m_tail;
61  node->next->prev = node;
62  node->prev = 0;
63  m_tail = node;
64  }
65 
66  m_id_map[id] = node;
67 }
68 
69 
70 bool RequestCache::remove(uint32_t id, DispatchHandler *&handler) {
71 
72  HT_DEBUGF("Removing id %d", id);
73 
74  IdHandlerMap::iterator iter = m_id_map.find(id);
75 
76  if (iter == m_id_map.end()) {
77  HT_DEBUGF("ID %d not found in request cache", id);
78  return false;
79  }
80 
81  CacheNode *node = (*iter).second;
82 
83  if (node->prev == 0)
84  m_tail = node->next;
85  else
86  node->prev->next = node->next;
87 
88  if (node->next == 0)
89  m_head = node->prev;
90  else
91  node->next->prev = node->prev;
92 
93  m_id_map.erase(iter);
94 
95  handler = node->dh;
96  delete node;
97  return true;
98 }
99 
100 
101 
102 
104  DispatchHandler *&dh,
105  ClockT::time_point *next_timeout) {
106 
107  bool handler_removed = false;
108  while (m_head && !handler_removed && m_head->expire <= now) {
109 
110  IdHandlerMap::iterator iter = m_id_map.find(m_head->id);
111  assert (iter != m_id_map.end());
112  CacheNode *node = m_head;
113  if (m_head->prev) {
114  m_head = m_head->prev;
115  m_head->next = 0;
116  }
117  else
118  m_head = m_tail = 0;
119 
120  m_id_map.erase(iter);
121 
122  if (node->handler != 0) {
123  handlerp = node->handler;
124  dh = node->dh;
125  handler_removed = true;
126  }
127  delete node;
128  }
129 
130  if (m_head)
131  *next_timeout = m_head->expire;
132  else
133  *next_timeout = ClockT::time_point();
134 
135  return handler_removed;
136 }
137 
138 
139 
140 void RequestCache::purge_requests(IOHandler *handler, int32_t error) {
141  for (CacheNode *node = m_tail; node != 0; node = node->next) {
142  if (node->handler == handler) {
143  String proxy = handler->get_proxy();
144  EventPtr event;
145  HT_DEBUGF("Purging request id %d", node->id);
146  if (proxy.empty())
147  event = make_shared<Event>(Event::ERROR, handler->get_address(), error);
148  else
149  event = make_shared<Event>(Event::ERROR, handler->get_address(), proxy, error);
150  handler->deliver_event(event, node->dh);
151  node->handler = 0; // mark for deletion
152  }
153  }
154 }
155 
void purge_requests(IOHandler *handler, int32_t error)
Purges all requests assocated with handler.
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
chrono::time_point< fast_clock > time_point
Definition: fast_clock.h:42
Abstract base class for application dispatch handlers registered with AsyncComm.
CacheNode * next
Doubly-linked list pointers.
Definition: RequestCache.h:58
InetAddr get_address()
Gets the handler socket address.
Definition: IOHandler.h:229
Internal cache node structure.
Definition: RequestCache.h:54
bool remove(uint32_t id, DispatchHandler *&handler)
Removes a request from the cache.
Definition: RequestCache.cc:70
std::shared_ptr< Event > EventPtr
Smart pointer to Event.
Definition: Event.h:228
STL namespace.
Error event
Definition: Event.h:64
#define HT_ASSERT(_e_)
Definition: Logger.h:396
const String & get_proxy()
Gets the proxy name for this connection.
Definition: IOHandler.h:247
Logging routines and macros.
Compatibility Macros for C/C++.
Base class for socket descriptor I/O handlers.
Definition: IOHandler.h:76
Declarations for RequestCache.
Declarations for IOHandlerData.
Hypertable definitions
void insert(uint32_t id, IOHandler *handler, DispatchHandler *dh, ClockT::time_point &expire)
Inserts pending request callback handler into cache.
Definition: RequestCache.cc:43
#define HT_DEBUGF(msg,...)
Definition: Logger.h:260
void deliver_event(EventPtr &event, DispatchHandler *dh=0)
Convenience method for delivering event to application.
Definition: IOHandler.h:169
DispatchHandler * dh
Callback handler to which MESSAGE, TIMEOUT, ERROR, and DISCONNECT events are delivered.
Definition: RequestCache.h:64
bool get_next_timeout(ClockT::time_point &now, IOHandler *&handlerp, DispatchHandler *&dh, ClockT::time_point *next_timeout)
Removes next request that has timed out.