45 if (!
mutex.enter(1000))
54 if (!
mutex.enter(1000))
64 if (!
mutex.enter(1000))
65 return "Locking error";
70 return "Request idle";
72 return "Request queued";
74 return "Request sent";
76 return "Request success";
78 return "Request failed";
80 return "Request timed out";
82 return "Request local error";
84 return "Request network error";
86 return "Request server error";
88 return "Request server too busy";
90 return "Error getting status";
96 if (!
mutex.enter(1000))
104 if (!
mutex.enter(1000))
112 if (!
mutex.enter(1000))
123 if (!
mutex.enter(1000))
138 if (!
mutex.enter(1000))
150 if (!
mutex.enter(1000))
160 if (!
mutex.enter(1000))
174 if (!
mutex.enter(1000))
187 if (!
mutex.enter(1000))
225 if (!
mutex.enter(1000, __FUNCTION__))
237 if (!
mutex.enter(1000, __FUNCTION__))
258 if (!
mutex.enter(1000, __FUNCTION__))
271 if (!
mutex.enter(1000, __FUNCTION__))
308 std::map<uint64, RequestReply*>::iterator i, e;
309 mutex.enter(1000, __FUNCTION__);
321 std::list<RequestGatewayConnection>::iterator i, e =
connections.end();
322 if (!
mutex.enter(1000, __FUNCTION__))
327 if ( (
stricmp((*i).addr.c_str(), addr.c_str()) == 0) && ((*i).port == port) ) {
345 msgConnect->
setString(
"URI",
"ClientConnect");
348 channel =
manager->addTCPConnection(con.
addr.c_str(), con.
port, con.
encryption,
PROTOCOL_MESSAGE,
true, 0,
this, con.
conID, con.
location, 1000, (
const char*)msgConnect->
data, msgConnect->
getSize());
368 if (!
mutex.enter(1000, __FUNCTION__))
392 if (!reply || !reply->
clientRef)
return false;
393 if (!
mutex.enter(1000, __FUNCTION__))
416 std::list<RequestGatewayConnection>::iterator i, e =
connections.end();
417 if (!
mutex.enter(1000, __FUNCTION__))
421 if ((*i).conID == conid) {
425 LogPrint(0,
LOG_SYSTEM, 0,
"Disconnected from gateway %u on %s:%u", conid, (*i).addr.c_str(), (*i).port);
426 (*i).lastFailTime = now;
427 (*i).lastConTime = 0;
432 LogPrint(0,
LOG_SYSTEM, 0,
"Connected to gateway %u on %s:%u", conid, (*i).addr.c_str(), (*i).port);
433 (*i).lastFailTime = 0;
434 (*i).lastConTime = now;
454 if (!msg)
return false;
455 if (!
mutex.enter(1000, __FUNCTION__)) {
461 std::map<uint64,RequestReply*>::iterator i =
requestMap.find(ref);
553 int32 heartbeatInterval = 3000;
554 uint64 lastHeartbeat = 0;
557 if (!lastHeartbeat ||
GetTimeAgeMS(lastHeartbeat) > heartbeatInterval) {
579 if (reply =
outQ.waitForAndTakeFirst(50))
590 if (!
conMutex.enter(1000, __FUNCTION__)) {
603 uint32 success = 0, failed = 0, notConnected = 0;
605 std::list<RequestGatewayConnection>::iterator iCon, eCon =
connections.end();
607 while (iCon != eCon) {
618 LogPrint(0,
LOG_SYSTEM, 2,
"Failed sending heartbeat from Client to %u gateways (%u succeeded)...", failed, success);
635 if (!
conMutex.enter(3000, __FUNCTION__))
637 std::list<RequestGatewayConnection>::iterator iCon, eCon =
connections.end();
639 while (iCon != eCon) {
642 if ((*iCon).conID && (*iCon).lastConTime) {
665 if (!
conMutex.enter(3000, __FUNCTION__))
667 std::list<RequestGatewayConnection>::iterator iCon, eCon =
connections.end();
669 while (iCon != eCon) {
670 if ((*iCon).conID &&
channel->isConnected((*iCon).conID)) {
671 channel->endConnection((*iCon).conID);
686 std::list<RequestGatewayConnection>::iterator iCon, eCon =
connections.end();
688 while (iCon != eCon) {
722 if ((tokenCount =
jsmn_parse(&parser, json, strlen(json), tokens, 1024)) <= 0) {
733 std::string value = std::string(val, valSize);
734 return value.c_str();
774 const char* json = replyMsg->
getString(
"JSON");
780 std::string jsonReply = json;
786 const char* key1,
const char* val1,
787 const char* key2,
const char* val2,
788 const char* key3,
const char* val3,
789 const char* key4,
const char* val4,
790 const char* key5,
const char* val5,
791 const char* key6,
const char* val6,
792 const char* key7,
const char* val7,
793 const char* key8,
const char* val8,
794 const char* key9,
const char* val9,
795 const char* key10,
const char* val10,
796 const char* key11,
const char* val11,
797 const char* key12,
const char* val12,
798 const char* key13,
const char* val13,
799 const char* key14,
const char* val14,
800 const char* key15,
const char* val15,
801 const char* key16,
const char* val16,
802 const char* key17,
const char* val17,
803 const char* key18,
const char* val18,
804 const char* key19,
const char* val19,
805 const char* key20,
const char* val20
808 msg->
setInt(
"HTTP_OPERATION", operation);
842 LogPrint(0, 0, 1,
"Could not connect to Face Server on %s:%u...", address, port);
850 RequestClient::CreateRequestMessage(
HTTP_POST,
"authenticate",
"email", username,
"password", password,
"clientid",
"1",
"locationid",
"1"),
852 LogPrint(0, 0, 1,
"Couldn't login to server account...");
856 if (!token.length()) {
861 LogPrint(0, 0, 1,
"Successfully logged in with token: %s...", token.c_str());
864 LogPrint(0, 0, 1,
"Couldn't connect to server...");
907 this->gatewayCount = 1;
925 std::list<RequestReply*> replyList;
926 std::list<RequestReply*>::iterator i, e = replyList.end();
929 int32 intervalMS = 1000;
931 intervalMS = (int32)(1000.0 /
sendfreq);
934 uint64 lastReconnect = 0;
936 int32 printIntervalMS = 3000;
938 uint32 stillWaiting, failed, timeout, errors, success, total, tooBusy, serverError;
939 stillWaiting = failed = timeout = errors = success = total = tooBusy = serverError = 0;
941 char* bigdata =
new char[
payload];
945 msgTemplate->
setString(
"URI",
"longtest");
973 LogPrint(0, 0, 1,
"Couldn't send request to server...");
1013 LogPrint(0, 0, 1,
"Couldn't post request to server...");
1017 replyList.push_back(reply);
1023 i = replyList.begin();
1052 i = replyList.erase(i);
1074 if (tooBusy || serverError || failed || timeout || errors)
1075 LogPrint(0,
LOG_SYSTEM, 0,
"%s[%u] success: %u of %u (w: %u): %.3fms - busy: %u servererror: %u failed: %u timeout: %u errors: %u\n",
1077 id, success, total, stillWaiting, responseTimes.
getAverage() / 1000.0, tooBusy, serverError, failed, timeout, errors);
1081 id, success, total, stillWaiting, responseTimes.
getAverage() / 1000.0);
1098 if (tooBusy || serverError || failed || timeout || errors)
1099 LogPrint(0,
LOG_SYSTEM, 0,
"Completed [%u] success: %u of %u (w: %u): %.3fms - busy: %u servererror: %u failed: %u timeout: %u errors: %u\n",
1100 id, success, total, stillWaiting, responseTimes.
getAverage() / 1000.0, tooBusy, serverError, failed, timeout, errors);
1103 id, success, total, stillWaiting, responseTimes.
getAverage() / 1000.0);
1147 this->gatewayCount = 1;
1163 int32 intervalMS = 1000;
1165 intervalMS = (int32)(1000.0 /
sendfreq);
1166 uint64 lastPost = 0;
1168 int32 printIntervalMS = 3000;
1170 uint32 stillWaiting, failed, timeout, errors, success, total, tooBusy, serverError;
1171 stillWaiting = failed = timeout = errors = success = total = tooBusy = serverError = 0;
1175 int8 encryption =
NOENC;
1177 char* bigdata =
new char[
payload];
1201 switch (reply->
type) {
1233 LogPrint(0,
LOG_SYSTEM, 0,
"[%u] finished total: %u success: %u busy: %u servererror: %u failed: %u timeout: %u errors: %u\n",
1234 id, total, success, tooBusy, serverError, failed, timeout, errors);
1240 LogPrint(0,
LOG_SYSTEM, 0,
"Client %u finishing up... (%u/%u) success: %u busy: %u servererror: %u failed: %u timeout: %u errors: %u\n",
1241 id, stillWaiting, total, success, tooBusy, serverError, failed, timeout, errors);
1243 LogPrint(0,
LOG_SYSTEM, 0,
"[%u] (%u/%u) success: %u busy: %u servererror: %u failed: %u timeout: %u errors: %u\n",
1244 id, stillWaiting, total, success, tooBusy, serverError, failed, timeout, errors);
1291 this->gatewayCount = 1;
1307 int32 intervalMS = 1000;
1309 intervalMS = (int32)(1000.0 /
sendfreq);
1310 uint64 lastPost = 0;
1312 int32 printIntervalMS = 3000;
1314 uint32 stillWaiting, failed, timeout, errors, success, total, tooBusy, serverError;
1315 stillWaiting = failed = timeout = errors = success = total = tooBusy = serverError = 0;
1319 int8 encryption =
NOENC;
1321 char* bigdata =
new char[
payload];
1354 LogPrint(0, 0, 1,
"Couldn't connect to Websocket server on: %s", url.c_str());
1360 ++c, uriString.c_str()).c_str());
1366 LogPrint(0, 0, 1,
"Lost connection to server...");
1391 LogPrint(0,
LOG_SYSTEM, 0,
"[%u] finished total: %u success: %u busy: %u servererror: %u failed: %u timeout: %u errors: %u\n",
1392 id, total, success, tooBusy, serverError, failed, timeout, errors);
1398 LogPrint(0,
LOG_SYSTEM, 0,
"Client %u finishing up... (%u/%u) success: %u busy: %u servererror: %u failed: %u timeout: %u errors: %u\n",
1399 id, stillWaiting, total, success, tooBusy, serverError, failed, timeout, errors);
1401 LogPrint(0,
LOG_SYSTEM, 0,
"[%u] (%u/%u) success: %u busy: %u servererror: %u failed: %u timeout: %u errors: %u\n",
1402 id, stillWaiting, total, success, tooBusy, serverError, failed, timeout, errors);
1438 const uint16 port = 38050;
1439 const uint32 reqCount = 20;
1440 const uint32 payload = 1024;
1447 unittest::fail(
"could not start message listener on localhost:%u", port);
1456 unittest::fail(
"could not add gateway localhost:%u to client", port);
1467 unittest::fail(
"server never received the client connect greeting");
1479 unittest::fail(
"client did not register as connected to localhost:%u", port);
1487 char* dat =
new char[payload];
1488 memset(dat, 7, payload);
1492 for (uint32 n = 0; n < reqCount; n++) {
1497 req->
setData(
"BigData", dat, payload);
1552 unittest::metric(
"request_throughput", (
double)reqCount / us * 1e6,
"req/s",
true);
1562 "Request client/gateway round-trip over localhost",
"network");
#define NOENC
Plain, unencrypted transport.
#define NETWORKEVENT_CONNECT
Connection established.
#define NETWORKEVENT_DISCONNECT_RETRYING
Connection lost; reconnection attempts in progress.
#define NETWORKEVENT_DISCONNECT
Connection closed for good.
#define NETWORKEVENT_RECONNECT
Connection re-established after a failure (autoreconnect).
#define HTTP_SERVICE_NOT_AVAILABLE
503 Service Unavailable
#define HTTP_MALFORMED_URL
400 Bad Request
#define HTTP_GATEWAY_TIMEOUT
504 Gateway Timeout
#define HTTP_SERVER_MALFORMED_REPLY
500 (malformed backend reply)
#define HTTP_INTERNAL_ERROR
500 Internal Server Error (page generation)
#define HTTP_MOVED_PERMANENTLY
301 Moved Permanently
#define HTTP_USE_LOCAL_COPY
304 Not Modified (use cached copy)
#define HTTP_ACCESS_DENIED
403 Forbidden
#define HTTP_FILE_NOT_FOUND
404 Not Found
#define HTTP_UNAUTHORIZED
401 Unauthorized (triggers Basic auth)
#define HTTP_SERVER_NOREPLY
500 (no reply from backend server)
#define HTTP_NOT_IMPLEMENTED
501 Not Implemented
#define PROTOCOL_MESSAGE
CMSDK binary DataMessage protocol (size-prefixed frames).
#define HTTP_SERVER_UNAVAILABLE
500 (backend server unavailable)
Request-system client side: RequestReply futures, RequestQueue, gateway connection records and the Re...
Small, dependency-free unit test harness used by all CMSDK object tests.
#define thread_ret_val(ret)
#define THREAD_FUNCTION_CALL
The central Psyclone data container: a self-contained binary message with typed, named user entries.
uint32 getSystemID()
getSystemID() Get and return message system id
bool setString(const char *key, const char *value)
setString(const char* key, const char* value)
bool setInt(const char *key, int64 value)
setInt(const char* key, int64 value)
DataMessageHeader * data
Pointer to the message's flat memory block (header + user entries).
bool setStatus(uint16 status)
setStatus(uint16 status)
uint16 getStatus()
getStatus()
uint32 getSize()
getSize() Get message size Many types of data of any size can be put into a message as user entries; ...
uint64 getReference()
getReference() Get and return message reference id
bool setReference(uint64 ref)
setReference(uint64 ref) Set message reference
bool setData(const char *key, const char *value, uint32 size)
setData(const char* key, const char* value, uint32 size)
const char * getString(const char *key)
getString(const char* key)
DataMessage * copy()
copy() Creates a full deep copy of the message and returns it.
A parsed or generated HTTP response.
uint8 type
HTTP_* status id of this reply.
A parsed or generated HTTP request (also used for WebSocket upgrade handshakes).
bool createRequest(uint8 type, const char *host, const char *uri, const char *content, uint32 contentSize, bool keepAlive, uint64 ifModifiedSince)
Build a simple request with optional raw body.
JSONM: a JSON document with attached binary chunks in one contiguous buffer.
uint32 addData(const char *name, const char *data, uint64 size, const char *type)
Append a binary attachment.
char * jmData
Owned serialised container buffer (JSON + attachments).
bool setJSON(const char *json)
Replace the JSON text portion (multipart metadata is regenerated).
One logical network interface: a group of listeners/connections with shared dispatch.
uint64 createWebsocketConnection(const char *url, const char *protocolName, const char *origin=NULL, uint32 timeoutMS=5000)
Open a client WebSocket connection from a full URL.
WebsocketData * waitForWebsocketData(uint64 &conid, uint32 ms)
Wait for the next queued WebSocket message.
bool sendMessage(DataMessage *msg, uint64 conid)
Send a DataMessage.
bool endConnection(uint64 conid)
Gracefully close a connection.
bool sendWebsocketData(WebsocketData *wsData, uint64 conid)
Send a WebSocket frame.
DataMessage * waitForMessage(uint64 &conid, uint32 ms)
Wait for the next queued DataMessage.
Central owner of all channels, listeners and connections in a process.
NetworkChannel * createWebsocketConnection(const char *url, uint32 channelID, NetworkReceiver *recv, uint64 &conid, const char *protocolName=NULL, const char *origin=NULL, uint32 timeoutMS=5000)
Open a client WebSocket connection from a full URL (ws:// or wss://).
NetworkChannel * createListener(uint16 port, uint8 encryption, uint8 protocol, bool isAsync, uint32 protocolTimeout, bool isDefaultProtocol, uint32 channelID, NetworkReceiver *recv)
Open a listening port for one or more protocols.
HTTPReply * makeHTTPRequest(const char *url, uint32 timeout, const char *content=NULL, uint32 contentSize=0)
Blocking HTTP(S) exchange from a URL string (GET, or POST when content given).
Application-facing client of the request system: posts DataMessage requests to one or more RequestGat...
bool receiveHTTPReply(HTTPReply *reply, HTTPRequest *req, NetworkChannel *channel, uint64 conid)
NetworkReceiver hook: HTTP replies (when talking to a gateway over HTTP).
uint64 lastRefID
Last issued client reference id.
static DataMessage * SendRequestAndWaitForReply(RequestClient *client, DataMessage *msg, int timeoutMS)
Convenience: post msg, wait, and return the reply message.
utils::Mutex conMutex
Guards connections.
std::map< uint64, RequestReply * > requestMap
In-flight requests by client reference id.
bool receiveNetworkEvent(NetworkEvent *evt, NetworkChannel *channel, uint64 conid)
NetworkReceiver hook: gateway connect/disconnect events (drives reconnection).
NetworkManager * manager
Owned network stack for gateway links.
bool run()
Worker loop: connection upkeep, outgoing queue, timeouts.
bool receiveMessage(DataMessage *msg, NetworkChannel *channel, uint64 conid)
NetworkReceiver hook: reply messages from gateways, matched to pending requests.
bool finishRequest(RequestReply *reply)
Release a RequestReply obtained from postRequest() back to the client's pool.
RequestReply * postRequest(DataMessage *msg)
Post a request asynchronously.
bool sendRequest(RequestReply *reply)
Serialise and send one request to the best available gateway.
bool reconnect()
Force reconnection of gateway links.
static bool TestServerLogin(const char *address, uint16 port, const char *username, const char *password, const char *reqAfterLogin)
Manual test: log in to a request server and issue a request.
static std::string SendRequestAndWaitForJSON(RequestClient *client, DataMessage *msg, int timeoutMS)
Convenience: post msg on client, wait, and return the reply's JSON text.
uint64 receivedCount
Total replies received.
uint32 sendStatusNow()
Send a status/heartbeat message to all gateways.
utils::WaitQueuePointer< RequestReply * > outQ
Outgoing requests awaiting dispatch.
static std::string GetJSONReplyParameter(const char *json, const char *name)
Extract a named top-level string value from a JSON reply.
bool addGateway(uint32 id, std::string addr, uint16 port, uint8 encryption=NOENC)
Register a gateway to connect to (may be called several times for redundancy).
static DataMessage * CreateRequestMessage(uint8 operation, const char *req, const char *key1=NULL, const char *val1=NULL, const char *key2=NULL, const char *val2=NULL, const char *key3=NULL, const char *val3=NULL, const char *key4=NULL, const char *val4=NULL, const char *key5=NULL, const char *val5=NULL, const char *key6=NULL, const char *val6=NULL, const char *key7=NULL, const char *val7=NULL, const char *key8=NULL, const char *val8=NULL, const char *key9=NULL, const char *val9=NULL, const char *key10=NULL, const char *val10=NULL, const char *key11=NULL, const char *val11=NULL, const char *key12=NULL, const char *val12=NULL, const char *key13=NULL, const char *val13=NULL, const char *key14=NULL, const char *val14=NULL, const char *key15=NULL, const char *val15=NULL, const char *key16=NULL, const char *val16=NULL, const char *key17=NULL, const char *val17=NULL, const char *key18=NULL, const char *val18=NULL, const char *key19=NULL, const char *val19=NULL, const char *key20=NULL, const char *val20=NULL)
Build a request DataMessage from an operation, request name and up to 20 key/value string pairs (NULL...
bool waitForConnection(uint32 timeoutMS)
Block until a gateway connection is established.
friend THREAD_RET THREAD_FUNCTION_CALL RequestClientRun(THREAD_ARG arg)
Thread entry point for the RequestClient worker loop.
bool sendMessageToGateway(DataMessage *msg, RequestGatewayConnection &con)
Send a message on a specific gateway link.
uint32 threadID
Worker thread id.
std::list< RequestGatewayConnection > connections
Configured gateways and their state.
NetworkChannel * channel
Channel carrying the gateway connections.
static RequestReply * SendRequestAndWaitForReplyObject(RequestClient *client, DataMessage *msg, int timeoutMS)
Convenience: post msg, wait, and return the whole RequestReply object.
uint64 sentCount
Total requests sent.
utils::Mutex mutex
Guards request bookkeeping.
Future/handle for one in-flight request: holds the request message, the eventual reply,...
DataMessage * peekRequestMessage()
RequestCallbackFunction callback
bool setRequestMessageCopy(DataMessage *msg)
Attach a copy of the outgoing request message (caller keeps msg).
bool setCallback(RequestCallbackFunction callback)
Register a completion callback (alternative to blocking waits).
bool setStatus(RequestStatus status)
Set the current lifecycle status (wakes waiters when terminal).
DataMessage * getRequestMessageCopy()
bool replyToRequest(DataMessage *msg, RequestStatus status)
Complete this request with a reply (called by the network layer).
RequestStatus getStatus()
bool giveReplyMessage(DataMessage *msg)
Attach the reply message, transferring ownership.
uint64 startTime
When the request was created (ms epoch).
uint64 getRequestDuration()
uint32 systemID
Id of the system/gateway this request belongs to.
std::string getStatusText()
RequestStatus waitForResult(uint32 timeoutMS)
Block until the request reaches a terminal status or the timeout expires.
uint32 getRequestDurationMS()
RequestCallbackFunction getCallback()
uint64 finishTime
When a terminal status was set (ms epoch; 0 while pending).
DataMessage * getReplyMessageCopy()
bool isInUse
Pooling flag: false once finishRequest() releases the object for reuse.
utils::Semaphore semaphore
uint64 clientRef
Client-side reference id correlating request and reply.
bool setReplyMessageCopy(DataMessage *msg)
Attach a copy of the reply message (caller keeps msg).
bool giveRequestMessage(DataMessage *msg)
Attach the outgoing request message, transferring ownership.
DataMessage * waitForMessage(uint32 timeoutMS, bool takeMessage=false)
Block for the reply message itself.
DataMessage * peekReplyMessage()
bool isRunning
Set by the worker while its loop is active.
virtual bool stop(uint32 timeout=200)
Ask the worker loop to finish and wait for it to do so.
bool shouldContinue
Loop-continuation flag; cleared by stop().
Sliding-window sample collector with average, variance, standard deviation and median.
bool add(double val)
Add a sample, evicting the oldest when the window is full.
friend THREAD_RET THREAD_FUNCTION_CALL TestRequestClientRun(THREAD_ARG arg)
bool init(uint16 port, uint32 gatewayCount, double sendfreq, int32 reconnectMS, uint32 payload, const char *longTestName)
TestRequestClient(uint32 id)
TestWebRequestClient(uint32 id)
bool init(uint16 port, uint32 gatewayCount, double sendfreq, int32 reconnectMS, uint32 payload, const char *longTestName)
friend THREAD_RET THREAD_FUNCTION_CALL TestWebRequestClientRun(THREAD_ARG arg)
bool init(uint16 port, uint32 gatewayCount, double sendfreq, int32 reconnectMS, uint32 payload, const char *longTestName)
TestWebSocketRequestClient(uint32 id)
friend THREAD_RET THREAD_FUNCTION_CALL TestWebSocketRequestClientRun(THREAD_ARG arg)
static bool CreateThread(THREAD_FUNCTION func, void *args, uint32 &newID, uint32 reqID=0)
Create a new native thread and start it immediately.
static UnitTestRunner & instance()
Access the singleton (created on first use).
void registerTest(const char *name, UnitTestFunc func, const char *description="", const char *category="", bool inDefaultRun=true)
Register a test with the runner.
One WebSocket frame/message (RFC 6455): parsing, generation and control frames.
char * data
Owned decoded payload bytes.
bool setData(DataType dataType, bool maskData, const char *data=NULL, uint64 size=0)
Set the payload and build the serialised frame for sending.
uint64 GetTimeNow()
Return the current absolute time (µs since year 0) according to the TMC.
int32 GetTimeAgeMS(uint64 t)
Age of a timestamp relative to now, in milliseconds.
RequestStatus
Lifecycle states of a request as it moves through client, gateway and executor.
void(* RequestCallbackFunction)(RequestReply &reply)
Signature for asynchronous completion callbacks registered on a RequestReply.
THREAD_RET THREAD_FUNCTION_CALL RequestClientRun(THREAD_ARG arg)
Thread entry point for the RequestClient worker loop.
bool Sleep(uint32 ms)
Suspend the calling thread.
std::string StringFormat(const char *format,...)
printf into a std::string.
const char * GetJSONValue(jsmntok_t *tokens, int tokenCount, const char *json, int token, int &valLength)
int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, jsmntok_t *tokens, unsigned int num_tokens)
Run JSON parser.
void jsmn_init(jsmn_parser *parser)
Create JSON parser over an array of tokens.
void fail(const char *fmt,...)
Set an explanatory reason shown on the FAIL line.
void metric(const char *name, double value, const char *unit="", bool higherIsBetter=true)
Record a performance metric.
void detail(const char *fmt,...)
Verbose-only indented diagnostic line (shown only when verbose=1).
void progress(int percent, const char *action)
Report progress with a short description of the current action.
static bool Test_RequestClient()
THREAD_RET THREAD_FUNCTION_CALL TestRequestClientRun(THREAD_ARG arg)
THREAD_RET THREAD_FUNCTION_CALL TestWebSocketRequestClientRun(THREAD_ARG arg)
THREAD_RET THREAD_FUNCTION_CALL TestWebRequestClientRun(THREAD_ARG arg)
void Register_RequestClient_Tests()
Notification of a connection lifecycle change (connect, disconnect, buffer state.....
uint8 type
NETWORKEVENT_* event type.
RequestQueue longReqQueue
Gateway-side queue of long requests for this peer.
RequestQueue shortReqQueue
Gateway-side queue of short requests for this peer.
uint32 removeStaleRequests(uint32 ttlMS)
Fail and drop requests older than ttlMS from both queues.
uint32 count
Total requests routed via this connection.
Client/executor-side record of one gateway it connects to.
uint8 encryption
NOENC or SSLENC for this link.
uint32 id
Gateway id (configuration key).
uint64 location
Resolved endpoint packed as uint64.
uint64 conID
NetworkManager connection id (0 when disconnected).
std::string addr
Gateway host name or IP.
uint64 lastFailTime
Last failed connect time (ms epoch; drives retry backoff).
uint64 lastConTime
Last successful connect time (ms epoch).
void clear()
Reset to the unconfigured/disconnected state.