1 #include "hmbdc/Copyright.hpp" 3 #include "hmbdc/app/Logger.hpp" 4 #include "hmbdc/tips/tcpcast/Transport.hpp" 5 #include "hmbdc/tips/tcpcast/Messages.hpp" 6 #include "hmbdc/tips/tcpcast/SendSession.hpp" 7 #include "hmbdc/time/Time.hpp" 8 #include "hmbdc/pattern/MonoLockFreeBuffer.hpp" 9 #include "hmbdc/comm/inet/Misc.hpp" 11 #include <unordered_set> 16 #include <netinet/tcp.h> 18 namespace hmbdc {
namespace tips {
namespace tcpcast {
20 namespace sendserver_detail {
24 ,
size_t toSendQueueMaxSize
28 , serverAddr_(serverFd_.localAddr)
29 , maxSendBatch_(config_.getExt<
size_t>(
"maxSendBatch"))
30 , outboundSubscriptions_(outboundSubscriptions) {
31 if (listen(serverFd_.fd, 10) < 0) {
32 HMBDC_THROW(std::runtime_error,
"failed to listen, errno=" << errno);
34 hmbdc::app::utils::EpollTask::instance().add(
35 hmbdc::app::utils::EpollTask::EPOLLIN
36 | hmbdc::app::utils::EpollTask::EPOLLET, serverFd_);
37 toSendQueue_.set_capacity(toSendQueueMaxSize);
41 decltype(advertisingMessages_) newAds;
42 tts.exportTo([&](uint16_t tag,
auto&& subCount) {
43 if (newAds.size() == 0
44 || !newAds.rbegin()->addTypeTag(tag)) {
45 newAds.emplace_back(serverFd_.localIp
47 , config_.
getExt<
bool>(
"loopback"));
48 newAds.rbegin()->addTypeTag(tag);
51 std::swap(advertisingMessages_, newAds);
52 for (
auto& m : advertisingMessages_) {
53 HMBDC_LOG_N(
"advertise at ", m);
57 auto const& advertisingMessages()
const {
58 return advertisingMessages_;
61 void queue(uint16_t tag
63 ,
size_t toSendByteSize
65 toSendQueue_.push_back(std::forward_as_tuple(tag, std::forward<ToSend>(toSend), toSendByteSize, it));
81 if (sessions_.size() == 0) {
86 auto newStartIt = begin;
88 auto minIndex = toSendQueue_.size();
89 for (
auto it = sessions_.begin(); it != sessions_.end();) {
90 if (minIndex > (*it)->toSendQueueIndex_) {
91 minIndex = (*it)->toSendQueueIndex_;
93 if (hmbdc_unlikely(!(*it)->runOnce())) {
94 sessions_.erase(it++);
100 newStartIt = std::get<3>(toSendQueue_[minIndex - 1]);
101 toSendQueue_.erase_begin(minIndex);
102 for (
auto it = sessions_.begin(); it != sessions_.end(); ++it) {
103 (*it)->toSendQueueIndex_ -= minIndex;
110 size_t readySessionCount()
const {
112 for (
auto const& s : sessions_) {
113 if (s->ready()) res++;
118 void killSlowestSession() {
119 for (
auto it = sessions_.begin(); it != sessions_.end(); ++it) {
120 if (0 == (*it)->toSendQueueIndex_) {
121 HMBDC_LOG_C((*it)->id(),
" too slow, dropping");
129 void doAccept() HMBDC_RESTRICT {
130 if (hmbdc_unlikely(serverFd_.isFdReady())) {
131 auto addrlen =
sizeof(serverAddr_);
132 auto conn = accept(serverFd_.fd, (
struct sockaddr *)&serverAddr_, (socklen_t*)&addrlen);
134 if (!serverFd_.checkErr()) {
135 HMBDC_LOG_C(
"accept failure, errno=", errno);
139 auto sz = config_.
getExt<
int>(
"tcpSendBufferBytes");
141 if (setsockopt(conn, SOL_SOCKET, SO_SNDBUF, &sz,
sizeof(sz)) < 0) {
142 HMBDC_LOG_C(
"failed to set send buffer size=", sz,
" errno=", errno);
145 int flag = config_.
getExt<
bool>(
"nagling")?0:1;
146 if (setsockopt(conn, IPPROTO_TCP, TCP_NODELAY, (
char*) &flag,
sizeof(flag)) < 0) {
147 HMBDC_LOG_C(
"failed to set TCP_NODELAY, errno=", errno);
150 auto s = std::make_shared<SendSession>(
151 conn, toSendQueue_, maxSendBatch_, outboundSubscriptions_);
153 }
catch (std::exception
const& e) {
154 HMBDC_LOG_C(e.what());
160 using Sessions = std::unordered_set<SendSession::ptr>;
162 ToSendQueue toSendQueue_;
164 sockaddr_in& serverAddr_;
165 mutable std::vector<TypeTagSource> advertisingMessages_;
167 size_t maxSendBatch_;
168 TypeTagSet& outboundSubscriptions_;
171 using SendServer = sendserver_detail::SendServer;
T getExt(const path_type ¶m, bool throwIfMissing=true) const
get a value from the config
Definition: Config.hpp:238
class to hold an hmbdc configuration
Definition: Config.hpp:44
Definition: SendServer.hpp:22
hmbdc::pattern::MonoLockFreeBuffer::iterator runOnce(hmbdc::pattern::MonoLockFreeBuffer::iterator begin, hmbdc::pattern::MonoLockFreeBuffer::iterator end) HMBDC_RESTRICT
run the server's async send function and decide which items in buffer can be release ...
Definition: SendServer.hpp:78
Definition: LockFreeBufferMisc.hpp:89