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
SimpleSendDataRequest.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_SEND_DATA_REQUEST_CC
20 #define SIMPLE_SEND_DATA_REQUEST_CC
21 
22 #include "InterfaceFunctions.h"
24 
25 #ifndef MAX_RETRIES
26 #define MAX_RETRIES 5
27 #endif
28 #ifndef HEADER_SIZE
29 #define HEADER_SIZE 20
30 #endif
31 
32 namespace pdb {
33 
34 template <class RequestType,
35  class DataType,
36  class ResponseType,
37  class ReturnType,
38  class... RequestTypeParams>
39 ReturnType simpleSendDataRequest(PDBLoggerPtr myLogger,
40  int port,
41  std::string address,
42  ReturnType onErr,
43  size_t bytesForRequest,
44  function<ReturnType(Handle<ResponseType>)> processResponse,
45  Handle<Vector<DataType>> dataToSend,
46  RequestTypeParams&&... args) {
47 
48  int retries = 0;
49 
50  while (retries <= MAX_RETRIES) {
51 
52  PDBCommunicator temp;
53  string errMsg;
54  bool success;
55 
56  if (temp.connectToInternetServer(myLogger, port, address, errMsg)) {
57  myLogger->error(errMsg);
58  myLogger->error("simpleSendDataRequest: not able to connect to server.\n");
59  std::cout << "ERROR: can't connect to remote server with port =" << port
60  << " and address =" << address << std::endl;
61  return onErr;
62  }
63 
64  // build the request
65  if (bytesForRequest < HEADER_SIZE) {
66  std::cout << "ERROR: block size is too small" << std::endl;
67  return onErr;
68  }
69  const UseTemporaryAllocationBlock tempBlock{bytesForRequest};
70  Handle<RequestType> request = makeObject<RequestType>(args...);
71  if (!temp.sendObject(request, errMsg)) {
72  myLogger->error(errMsg);
73  myLogger->error("simpleSendDataRequest: not able to send request to server.\n");
74  if (retries < MAX_RETRIES) {
75  retries++;
76  continue;
77  } else {
78  return onErr;
79  }
80  }
81  // now, send the data
82  if (!temp.sendObject(dataToSend, errMsg)) {
83  myLogger->error(errMsg);
84  myLogger->error("simpleSendDataRequest: not able to send data to server.\n");
85  if (retries < MAX_RETRIES) {
86  retries++;
87  continue;
88  } else {
89  return onErr;
90  }
91  }
92 
93  // get the response and process it
94  size_t objectSize = temp.getSizeOfNextObject();
95  if (objectSize == 0) {
96  myLogger->error("simpleRequest: not able to get next object size");
97  std::cout << "simpleRequest: not able to get next object size" << std::endl;
98  if (retries < MAX_RETRIES) {
99  retries++;
100  continue;
101  } else {
102  return onErr;
103  }
104  }
105  void* memory = malloc(objectSize);
106  if (memory == nullptr) {
107  myLogger->error(std::string("FATAL ERROR: not able to allocate memory with size=") +
108  std::to_string(objectSize));
109  std::cout << "FATAL ERROR: not able to allocate memory" << std::endl;
110  exit(-1);
111  }
112  ReturnType finalResult;
113  {
114  Handle<ResponseType> result = temp.getNextObject<ResponseType>(memory, success, errMsg);
115  if (!success) {
116  myLogger->error(errMsg);
117  myLogger->error("simpleRequest: not able to get next object over the wire.\n");
118  // JiaNote: we need free memory here!!!
119  free(memory);
120  if (retries < MAX_RETRIES) {
121  retries++;
122  continue;
123  } else {
124  return onErr;
125  }
126  }
127 
128  finalResult = processResponse(result);
129  }
130 
131  free(memory);
132  return finalResult;
133  }
134  return onErr;
135 }
136 }
137 #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
std::shared_ptr< PDBLogger > PDBLoggerPtr
Definition: PDBLogger.h:40
ReturnType simpleSendDataRequest(PDBLoggerPtr myLogger, int port, std::string address, ReturnType onErr, size_t bytesForRequest, function< ReturnType(Handle< ResponseType >)> processResponse, Handle< Vector< DataType >> dataToSend, RequestTypeParams &&...args)
#define HEADER_SIZE