#define HMBDC_ALOG_CONTEXT hmbdc::app::Context<40>
#include "hmbdc/app/utils/AsyncLoggerT.hpp"
#include <iostream>
#include <memory>
#include <unistd.h>
#include <sys/mman.h>
using MyContext = HMBDC_ALOG_CONTEXT;
struct Request
Request(uint16_t srcId, uint64_t id)
: srcId(srcId)
, id(id)
{}
uint16_t srcId;
uint64_t id;
friend
std::ostream& operator << (std::ostream& os, Request const& m) {
os << "Request " << m.srcId << ' ' << m.id;
return os;
}
};
struct Response
Response(Request const& r)
: srcId(r.srcId)
, respToId(r.id)
{}
uint16_t srcId;
uint64_t respToId;
friend
std::ostream& operator << (std::ostream& os, Response const& m) {
os << "Response " << m.srcId << ' ' << m.respToId;
return os;
}
};
struct Finish
Finish(uint16_t srcId)
: srcId(srcId)
{}
uint16_t srcId;
friend
std::ostream& operator << (std::ostream& os, Finish const& fin) {
os << "Finish " << fin.srcId;
return os;
}
};
struct MyClient
:
Client<MyClient, Request, Response> {
MyClient(MyContext* myCtx, uint64_t workLoad, uint64_t clientCount, uint16_t srcId)
: myCtx(myCtx)
, srcId(srcId)
, requestId(0u)
, workLoad(workLoad)
, clientCount(clientCount)
, respCount(0u) {
}
void kickStart() {
if (workLoad) {
Request r(srcId, requestId);
HMBDC_ALOG_N(srcId, ':', "--> ", r);
myCtx->send(r);
}
}
void handleMessageCb(Request const& r) {
HMBDC_ALOG_N(srcId, ':', "<-- ", r);
Response resp(r);
HMBDC_ALOG_N(srcId, ':', "--> ", resp);
myCtx->template send(resp);
}
void handleMessageCb(Response const& resp) {
if (resp.srcId == srcId &&
resp.respToId == requestId) {
HMBDC_ALOG_N(srcId, ':', "<-- ", resp);
if (++respCount == clientCount) {
workLoad--;
respCount = 0u;
++requestId;
if (workLoad) {
Request r(srcId, requestId);
HMBDC_ALOG_N(srcId, ':', "--> ", r);
myCtx->send(r);
} else {
Finish fin(srcId);
myCtx->send(fin);
HMBDC_ALOG_N(srcId, ':', "--> ", fin);
}
}
}
}
void stoppedCb(std::exception const& e) override {
HMBDC_ALOG_C(e.what());
};
std::tuple<char const*, int> schedSpec() const {
return std::make_tuple<char const*, int>(nullptr, 19);
}
MyContext* myCtx;
uint16_t srcId;
uint64_t requestId;
uint64_t workLoad;
uint64_t clientCount;
uint64_t respCount;
};
struct Monitor
:
Client<Monitor, Request, Response, Finish> {
Monitor(uint16_t count)
: count(count)
, totalRequest(0u)
, totalResponse(0u)
{}
char const* hmbdcName() const { return "monitor"; }
std::tuple<char const*, int> schedSpec() const {
return std::make_tuple<char const*, int>(nullptr, 19);
}
void handleMessageCb(Finish const& fin) {
count--;
}
void handleMessageCb(Request const&) {
totalRequest++;
}
void handleMessageCb(Response const& resp) {
totalResponse++;
}
void report() const {
HMBDC_ALOG_N("totalRequest= ", totalRequest);
HMBDC_ALOG_N("totalResponse= ", totalResponse);
}
uint16_t count;
size_t totalRequest;
size_t totalResponse;
};
int main() {
const uint64_t workLoad = 2;
const uint16_t clientCount = 3u;
MyContext ctx(20u, clientCount);
std::unique_ptr<MyClient> clients[clientCount];
Monitor mon(clientCount);
for (uint16_t i = 0; i < clientCount; ++i) {
clients[i].reset(new MyClient(&ctx, workLoad, clientCount, i));
ctx.addToPool(*clients[i]);
}
ctx.start(3, 0x07ul, mon, 0ul);
for (uint16_t i = 0; i < clientCount; ++i) {
clients[i]->kickStart();
}
while (mon.count){
sleep(1);
}
mon.report();
sleep(1);
ctx.stop();
ctx.join();
}