1 /*
2  * Copyright (C) 1996-2021 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 #ifndef SQUID_IPC_INQUIRER_H
12 #define SQUID_IPC_INQUIRER_H
13 
14 #include "base/AsyncJob.h"
15 #include "base/AsyncJobCalls.h"
16 #include "ipc/forward.h"
17 #include "ipc/Request.h"
18 #include "ipc/Response.h"
19 #include "ipc/StrandCoords.h"
20 #include <map>
21 
22 namespace Ipc
23 {
24 
25 /// Coordinator's job that sends a cache manage request to each strand,
26 /// aggregating individual strand responses and dumping the result if needed
27 class Inquirer: public AsyncJob
28 {
29     CBDATA_CLASS(Inquirer);
30 
31 public:
32     Inquirer(Request::Pointer aRequest, const Ipc::StrandCoords& coords, double aTimeout);
33     virtual ~Inquirer();
34 
35     /// finds and calls the right Inquirer upon strand's response
36     static void HandleRemoteAck(const Response& response);
37 
38     /* has-to-be-public AsyncJob API */
39     virtual void callException(const std::exception& e);
40 
41 protected:
42     /* AsyncJob API */
43     virtual void start();
44     virtual void swanSong();
45     virtual bool doneAll() const;
46     virtual const char *status() const;
47 
48     /// inquire the next strand
49     virtual void inquire();
50     /// perform cleanup actions on completion of job
51     virtual void cleanup();
52     /// do specific exception handling
53     virtual void handleException(const std::exception& e);
54     /// send response to client
55     virtual void sendResponse() = 0;
56     /// perform aggregating of responses and returns true if need to continue
57     virtual bool aggregate(Response::Pointer aResponse) = 0;
58 
59 private:
60     typedef UnaryMemFunT<Inquirer, Response::Pointer, Response::Pointer> HandleAckDialer;
61 
62     void handleRemoteAck(Response::Pointer response);
63 
64     static AsyncCall::Pointer DequeueRequest(unsigned int requestId);
65 
66     static void RequestTimedOut(void* param);
67     void requestTimedOut();
68     void removeTimeoutEvent();
69 
70 protected:
71     Request::Pointer request; ///< cache manager request received from client
72 
73     Ipc::StrandCoords strands; ///< all strands we want to query, in order
74     Ipc::StrandCoords::const_iterator pos; ///< strand we should query now
75 
76     const double timeout; ///< number of seconds to wait for strand response
77 
78     /// maps request->id to Inquirer::handleRemoteAck callback
79     typedef std::map<unsigned int, AsyncCall::Pointer> RequestsMap;
80     static RequestsMap TheRequestsMap; ///< pending strand requests
81 
82     static unsigned int LastRequestId; ///< last requestId used
83 };
84 
85 } // namespace Ipc
86 
87 #endif /* SQUID_IPC_INQUIRER_H */
88 
89