Esempio n. 1
0
/* when a period comes, the request is processed here */
void handleRequest()
{
    char firstChar = dequeue(&requestBuffer), secondChar = dequeue(&requestBuffer);
    if(firstChar == 'M' && secondChar == 'C')
        handleMessageCount();
    else if(firstChar == 'R' && secondChar == 'M')
        handleReadMessage();
    else if(firstChar == 'D' && secondChar == 'E')
        handleDeleteMessage();
    else if(firstChar == 'S' && secondChar == 'M')
        handleSendMessage();
    else if(firstChar == 'U' && secondChar == 'M')
        handleUpdateMessage();
    else
        sendInvalidRequestReply();

    /* then enqueue a period, flush the remainder of the request, and notify the send uart thread */
    enqueue(&replyBuffer, '.');
    while(dequeue(&requestBuffer) != '.');
    tx_event_flags_set(&gUartSendEventFlags,1,TX_OR);
}
Esempio n. 2
0
void InnerTcpConnection::realSendMessage() {
  function_footprint();
  static uint32_t BATCH_TCP_MESSAGES = InnerTcpConnection::innerTcpServer->getTcpBatchSize();

  InnerTcpConnectionState expectedState = READY;
  if(!state.compare_exchange_strong(expectedState, WRITING)) {
    VLOG(3) << "Connection is not ready: " << state.load();
    return;
  }
  auto conn = shared_from_this();
  if(unlikely(!socket.is_open())) {
    terminate();
    return;
  }

  idgs::actor::ActorMessagePtr msg;
  std::vector<idgs::actor::ActorMessagePtr>* msgs = new std::vector<idgs::actor::ActorMessagePtr>();
  msgs->reserve(BATCH_TCP_MESSAGES);
  std::vector<asio::const_buffer> outBuffers;
  outBuffers.reserve(BATCH_TCP_MESSAGES * 2 + 1);

  uint32_t sendLength;
  sendLength = 0;
  outBuffers.push_back(asio::buffer(reinterpret_cast<void*>(&sendLength), sizeof(sendLength)));

  while(getQueue().try_pop(msg)) {
    DVLOG(2) << "send message: " << msg->toString();
    DVLOG(3) << "Send head size: " << sizeof(idgs::net::TcpHeader) <<  ", content: " << dumpBinaryBuffer(std::string((char*)msg->getRpcBuffer()->getHeader(), sizeof(idgs::net::TcpHeader)));
    DVLOG(3) << "Send body size: " << msg->getRpcBuffer()->getBodyLength() <<  ", content: " << dumpBinaryBuffer(std::string(msg->getRpcBuffer()->getBody(), msg->getRpcBuffer()->getBodyLength()));

    msgs->push_back(msg);

    outBuffers.push_back(asio::buffer(reinterpret_cast<void*>(msg->getRpcBuffer()->getHeader()), sizeof(idgs::net::TcpHeader)));
    outBuffers.push_back(asio::buffer(reinterpret_cast<void*>(msg->getRpcBuffer()->getBody()), msg->getRpcBuffer()->getBodyLength()));
    sendLength += sizeof(idgs::net::TcpHeader) + msg->getRpcBuffer()->getBodyLength();

    //    if(msgs->size() >= BATCH_TCP_MESSAGES || sendLength > (1024 * 50)) {
    if(msgs->size() >= BATCH_TCP_MESSAGES) {
      break;
    }
  }

  if(msgs->empty()) {
    DVLOG(2) << "No availabe message to send.";
    state.store(READY);
    delete msgs;
    return;
  }
  try {
    DVLOG(2) << "Send " << msgs->size() << " messages";
    if(unlikely(!socket.is_open())) {
      // @fixme messagea lost
      delete msgs;
      terminate();
      return;
    }
    asio::async_write(
        socket,
        outBuffers,
        asio::transfer_all(),
        [msgs, conn] (const asio::error_code& error, const std::size_t& bytes_transferred) {
      DVLOG(2) << "Sent " << msgs->size() << " messages";
      conn->handleSendMessage(error);

      static NetworkStatistics* stats = InnerTcpConnection::innerTcpServer->network->getNetworkStatistics();
      stats->innerTcpBytesSent.fetch_add(bytes_transferred);
      stats->innerTcpPacketSent.fetch_add(msgs->size());

      delete msgs;
    }
    );
  } catch (std::exception& e) {
    LOG(ERROR) << "send message error, exception: " << e.what() << ", messages: " << msgs->size();
    delete msgs;
    terminate();
  } catch (...) {
    LOG(ERROR) << "send message error " << ", messages: " << msgs->size();
    catchUnknownException();
    delete msgs;
    terminate();
  }
}