A platform for high-performance distributed tool and library development written in C++. It can be deployed in two different cluster modes: standalone or distributed. API for v0.5.0, released on June 13, 2018.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SimpleRequest.cc
Go to the documentation of this file.
1 /*****************************************************************************
2  * *
3  * Copyright 2018 Rice University *
4  * *
5  * Licensed under the Apache License, Version 2.0 (the "License"); *
6  * you may not use this file except in compliance with the License. *
7  * You may obtain a copy of the License at *
8  * *
9  * http://www.apache.org/licenses/LICENSE-2.0 *
10  * *
11  * Unless required by applicable law or agreed to in writing, software *
12  * distributed under the License is distributed on an "AS IS" BASIS, *
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
14  * See the License for the specific language governing permissions and *
15  * limitations under the License. *
16  * *
17  *****************************************************************************/
18 
19 #ifndef SIMPLE_REQUEST_CC
20 #define SIMPLE_REQUEST_CC
21 
22 #include <functional>
23 #include <string>
24 
25 #include "InterfaceFunctions.h"
27 #include "PDBCommunicator.h"
28 
29 using std::function;
30 using std::string;
31 
32 #ifndef MAX_RETRIES
33 #define MAX_RETRIES 5
34 #endif
35 #define BLOCK_HEADER_SIZE 20
36 namespace pdb {
37 
38 template <class RequestType, class ResponseType, class ReturnType, class... RequestTypeParams>
39 ReturnType simpleRequest(PDBLoggerPtr myLogger,
40  int port,
41  std::string address,
42  ReturnType onErr,
43  size_t bytesForRequest,
44  function<ReturnType(Handle<ResponseType>)> processResponse,
45  RequestTypeParams&&... args) {
46 
47  int numRetries = 0;
48 
49  while (numRetries <= MAX_RETRIES) {
50  PDBCommunicator temp;
51  string errMsg;
52  bool success;
53 
54  if (temp.connectToInternetServer(myLogger, port, address, errMsg)) {
55  myLogger->error(errMsg);
56  myLogger->error("simpleRequest: not able to connect to server.\n");
57  // return onErr;
58  std::cout << "ERROR: can not connect to remote server with port=" << port
59  << " and address=" << address << std::endl;
60  return onErr;
61  }
62  myLogger->info(std::string("Successfully connected to remote server with port=") +
63  std::to_string(port) + std::string(" and address=") + address);
64  PDB_COUT << "Successfully connected to remote server with port=" << port
65  << " and address=" << address << std::endl;
66  // build the request
67  PDB_COUT << "bytesForRequest=" << bytesForRequest << std::endl;
68  if (bytesForRequest <= BLOCK_HEADER_SIZE) {
69  std::cout << "ERROR: too small buffer size for processing simple request" << std::endl;
70  return onErr;
71  }
72  const UseTemporaryAllocationBlock tempBlock{bytesForRequest};
73  PDB_COUT << "to make object" << std::endl;
74  Handle<RequestType> request = makeObject<RequestType>(args...);
75  PDB_COUT << "to send object" << std::endl;
76  if (!temp.sendObject(request, errMsg)) {
77  myLogger->error(errMsg);
78  myLogger->error("simpleRequest: not able to send request to server.\n");
79  if (numRetries < MAX_RETRIES) {
80  numRetries++;
81  continue;
82  } else {
83  return onErr;
84  }
85  }
86  PDB_COUT << "sent object..." << std::endl;
87  // get the response and process it
88  ReturnType finalResult;
89  size_t objectSize = temp.getSizeOfNextObject();
90  if (objectSize == 0) {
91  if (numRetries < MAX_RETRIES) {
92  numRetries++;
93  continue;
94  } else {
95  return onErr;
96  }
97  }
98  void* memory = malloc(objectSize);
99  if (memory == nullptr) {
100  errMsg = "FATAL ERROR in simpleRequest: Can't allocate memory";
101  myLogger->error(errMsg);
102  std::cout << errMsg << std::endl;
103  exit(-1);
104  }
105  {
106  Handle<ResponseType> result = temp.getNextObject<ResponseType>(memory, success, errMsg);
107  if (!success) {
108  myLogger->error(errMsg);
109  myLogger->error("simpleRequest: not able to get next object over the wire.\n");
111 
112  free(memory);
113  if (numRetries < MAX_RETRIES) {
114  numRetries++;
115  continue;
116  } else {
117  return onErr;
118  }
119  }
120 
121  finalResult = processResponse(result);
122  }
123  free(memory);
124  return finalResult;
125  }
126  return onErr;
127 }
128 
129 template <class RequestType, class SecondRequestType, class ResponseType, class ReturnType>
130 ReturnType simpleDoubleRequest(PDBLoggerPtr myLogger,
131  int port,
132  std::string address,
133  ReturnType onErr,
134  size_t bytesForRequest,
135  function<ReturnType(Handle<ResponseType>)> processResponse,
136  Handle<RequestType>& firstRequest,
137  Handle<SecondRequestType>& secondRequest) {
138 
139  PDBCommunicator temp;
140  string errMsg;
141  bool success;
142 
143  if (temp.connectToInternetServer(myLogger, port, address, errMsg)) {
144  myLogger->error(errMsg);
145  myLogger->error("simpleRequest: not able to connect to server.\n");
146  // return onErr;
147  std::cout << "ERROR: can not connect to remote server with port=" << port
148  << " and address=" << address << std::endl;
149  return onErr;
150  }
151  std::cout << "Successfully connected to remote server with port=" << port
152  << " and address=" << address << std::endl;
153  // build the request
154  if (!temp.sendObject(firstRequest, errMsg)) {
155  myLogger->error(errMsg);
156  myLogger->error("simpleDoubleRequest: not able to send first request to server.\n");
157  return onErr;
158  }
159 
160  if (!temp.sendObject(secondRequest, errMsg)) {
161  myLogger->error(errMsg);
162  myLogger->error("simpleDoubleRequest: not able to send second request to server.\n");
163  return onErr;
164  }
165 
166  // get the response and process it
167  ReturnType finalResult;
168  void* memory = malloc(temp.getSizeOfNextObject());
169  {
170  Handle<ResponseType> result = temp.getNextObject<ResponseType>(memory, success, errMsg);
171  if (!success) {
172  myLogger->error(errMsg);
173  myLogger->error("simpleRequest: not able to get next object over the wire.\n");
174  return onErr;
175  }
176 
177  finalResult = processResponse(result);
178  }
179  free(memory);
180  return finalResult;
181 }
182 }
183 #endif
bool sendObject(Handle< ObjType > &sendMe, std::string &errMsg)
bool connectToInternetServer(PDBLoggerPtr logToMeIn, int portNumber, std::string serverAddress, std::string &errMsg)
Handle< ObjType > getNextObject(void *readToHere, bool &success, std::string &errMsg)
#define MAX_RETRIES
ReturnType simpleDoubleRequest(PDBLoggerPtr myLogger, int port, std::string address, ReturnType onErr, size_t bytesForRequest, function< ReturnType(Handle< ResponseType >)> processResponse, Handle< RequestType > &firstRequest, Handle< SecondRequestType > &secondRequest)
#define PDB_COUT
Definition: PDBDebug.h:31
std::shared_ptr< PDBLogger > PDBLoggerPtr
Definition: PDBLogger.h:40
ReturnType simpleRequest(PDBLoggerPtr myLogger, int port, std::string address, ReturnType onErr, size_t bytesForRequest, function< ReturnType(Handle< ResponseType >)> processResponse, RequestTypeParams &&...args)
#define BLOCK_HEADER_SIZE