Forwarder.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 54 Interprocess Communication */
10 
11 #include "squid.h"
12 #include "base/AsyncJobCalls.h"
13 #include "base/TextException.h"
14 #include "errorpage.h"
15 #include "HttpReply.h"
16 #include "HttpRequest.h"
17 #include "ipc/Forwarder.h"
18 #include "ipc/Port.h"
19 #include "ipc/RequestId.h"
20 #include "ipc/TypedMsgHdr.h"
21 
24 
25 Ipc::Forwarder::Forwarder(Request::Pointer aRequest, double aTimeout):
26  AsyncJob("Ipc::Forwarder"),
27  codeContext(CodeContext::Current()),
28  request(aRequest), timeout(aTimeout)
29 {
30 }
31 
33 {
35  Must(request->requestId == 0);
36  });
37 }
38 
39 void
41 {
42  debugs(54, 3, MYNAME);
43 
44  typedef NullaryMemFunT<Forwarder> Dialer;
45  AsyncCall::Pointer callback = JobCallback(54, 5, Dialer, this, Forwarder::handleRemoteAck);
46  if (++LastRequestId == 0) // don't use zero value as request->requestId
47  ++LastRequestId;
48  request->requestId = LastRequestId;
49  TheRequestsMap[request->requestId] = callback;
50  TypedMsgHdr message;
51 
52  try {
53  request->pack(message);
54  } catch (...) {
55  // assume the pack() call failed because the message did not fit
56  // TODO: add a more specific exception?
57  handleError();
58  return;
59  }
60 
62  eventAdd("Ipc::Forwarder::requestTimedOut", &Forwarder::RequestTimedOut,
63  this, timeout, 0, false);
64 }
65 
66 void
68 {
69  debugs(54, 5, MYNAME);
70  removeTimeoutEvent();
71  if (request->requestId > 0) {
72  DequeueRequest(request->requestId);
73  request->requestId = 0;
74  }
75 }
76 
77 bool
79 {
80  debugs(54, 5, MYNAME);
81  return request->requestId == 0;
82 }
83 
85 void
87 {
88  debugs(54, 3, MYNAME);
89  request->requestId = 0;
90  // Do not do entry->complete() because it will trigger our client side
91  // processing when we no longer own the client-Squid connection.
92  // Let job cleanup close the client-Squid connection that Coordinator
93  // now owns.
94 }
95 
97 void
99 {
100  debugs(54, 3, MYNAME);
101  Must(param != nullptr);
102  Forwarder* fwdr = static_cast<Forwarder*>(param);
103  // use async call to enable job call protection that time events lack
104 
105  CallBack(fwdr->codeContext, [&fwdr] {
106  CallJobHere(54, 5, fwdr, Forwarder, requestTimedOut);
107  });
108 }
109 
111 void
113 {
114  debugs(54, 3, MYNAME);
115  handleTimeout();
116 }
117 
118 void
120 {
121  mustStop("error");
122 }
123 
124 void
126 {
127  mustStop("timeout");
128 }
129 
131 void
132 Ipc::Forwarder::handleException(const std::exception& e)
133 {
134  debugs(54, 3, e.what());
135  mustStop("exception");
136 }
137 
138 void
139 Ipc::Forwarder::callException(const std::exception& e)
140 {
141  try {
142  handleException(e);
143  } catch (const std::exception& ex) {
144  debugs(54, DBG_CRITICAL, ex.what());
145  }
147 }
148 
152 {
153  debugs(54, 3, MYNAME);
154  Must(requestId != 0);
155  AsyncCall::Pointer call;
156  RequestsMap::iterator request = TheRequestsMap.find(requestId);
157  if (request != TheRequestsMap.end()) {
158  call = request->second;
159  Must(call != nullptr);
160  TheRequestsMap.erase(request);
161  }
162  return call;
163 }
164 
166 void
168 {
171 }
172 
173 void
175 {
176  debugs(54, 3, MYNAME);
177  Must(requestId != 0);
178 
179  AsyncCall::Pointer call = DequeueRequest(requestId);
180  if (call != nullptr)
181  ScheduleCallHere(call);
182 }
183 
int eventFind(EVH *func, void *arg)
Definition: event.cc:145
static RequestsMap TheRequestsMap
pending Coordinator requests
Definition: Forwarder.h:70
static RequestId::Index LastRequestId
last requestId used
Definition: Forwarder.h:72
static void RequestTimedOut(void *param)
Ipc::Forwarder::requestTimedOut wrapper.
Definition: Forwarder.cc:98
static void HandleRemoteAck(RequestId)
finds and calls the right Forwarder upon Coordinator's response
Definition: Forwarder.cc:174
#define DBG_CRITICAL
Definition: Stream.h:37
void eventDelete(EVH *func, void *arg)
Definition: event.cc:127
void handleRemoteAck()
called when Coordinator starts processing the request
Definition: Forwarder.cc:86
#define ScheduleCallHere(call)
Definition: AsyncCall.h:166
virtual void handleException(const std::exception &e)
terminate with an error
Definition: Forwarder.cc:132
static InquirerPointer DequeueRequest(const RequestId::Index requestId)
returns and forgets the Inquirer waiting for the given requests
Definition: Inquirer.cc:43
void swanSong() override
Definition: Forwarder.cc:67
void CallBack(const CodeContext::Pointer &callbackContext, Fun &&callback)
Definition: CodeContext.h:126
std::map< RequestId::Index, AsyncCall::Pointer > RequestsMap
maps request->id to Forwarder::handleRemoteAck callback
Definition: Forwarder.h:69
static String CoordinatorAddr()
get the IPC message address for coordinator process
Definition: Port.cc:65
void callException(const std::exception &e) override
called when the job throws during an async call
Definition: Forwarder.cc:139
void requestTimedOut()
called when Coordinator fails to start processing the request [in time]
Definition: Forwarder.cc:112
virtual void handleTimeout()
Definition: Forwarder.cc:125
void SendMessage(const String &toAddress, const TypedMsgHdr &message)
Definition: UdsOp.cc:188
~Forwarder() override
Definition: Forwarder.cc:32
static AsyncCall::Pointer DequeueRequest(RequestId::Index)
returns and forgets the right Forwarder callback for the request
Definition: Forwarder.cc:151
#define JobCallback(dbgSection, dbgLevel, Dialer, job, method)
Convenience macro to create a Dialer-based job callback.
Definition: AsyncJobCalls.h:70
virtual void handleError()
Definition: Forwarder.cc:119
CodeContextPointer codeContext
Definition: Forwarder.h:43
#define Must(condition)
Definition: TextException.h:75
unsigned int Index
Definition: RequestId.h:27
struct msghdr with a known type, fixed-size I/O and control buffers
Definition: TypedMsgHdr.h:34
#define MYNAME
Definition: Stream.h:219
void start() override
called by AsyncStart; do not call directly
Definition: Forwarder.cc:40
bool doneAll() const override
whether positive goal has been reached
Definition: Forwarder.cc:78
#define SWALLOW_EXCEPTIONS(code)
Definition: TextException.h:79
virtual void callException(const std::exception &e)
called when the job throws during an async call
Definition: AsyncJob.cc:143
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
Forwarder(Request::Pointer aRequest, double aTimeout)
Definition: Forwarder.cc:25
void eventAdd(const char *name, EVH *func, void *arg, double when, int weight, bool cbdata)
Definition: event.cc:107
void removeTimeoutEvent()
called when we are no longer waiting for Coordinator to respond
Definition: Forwarder.cc:167

 

Introduction

Documentation

Support

Miscellaneous