SendResult_ptr DefaultMQProducerImpl::sendKernelImpl(Message_ptr msg, MessageQueue* mq, std::string& communicationMode, bool sendCallback) { std::string brokerAddr = this->mQClientFactory->findBrokerAddressInPublish(mq->getBrokerName()); if (brokerAddr.empty()) { // TODO 此处可能对Name Server压力过大,需要调优 this->mQClientFactory->updateTopicRouteInfoFromNameServer(mq->getTopic()); this->mQClientFactory->updateTopicRouteInfoFromNameServer(mq->getTopic(), true, this->defaultMQProducer); brokerAddr = this->mQClientFactory->findBrokerAddressInPublish(mq->getBrokerName()); } if (!brokerAddr.empty()) { std::string prevBody = msg->getBody(); int sysFlag = 0; SendMessageRequestHeader_var requestHeader = new SendMessageRequestHeader(); requestHeader->setProducerGroup(this->defaultMQProducer->getProducerGroup()); requestHeader->setTopic(msg->getTopic()); requestHeader->setDefaultTopic(this->defaultMQProducer->getCreateTopicKey()); requestHeader->setDefaultTopicQueueNums(this->defaultMQProducer->getDefaultTopicQueueNums()); requestHeader->setQueueId(mq->getQueueId()); requestHeader->setSysFlag(sysFlag); requestHeader->setBornTimestamp(112233); requestHeader->setFlag(msg->getFlag()); SendResult_var sendResult = new SendResult(); this->mQClientFactory->getMQClientAPIImpl()->sendMessage(brokerAddr, mq->getBrokerName(), SendMessageRequestHeader_var::Duplicate(requestHeader), 3); return SendResult_var::Duplicate(sendResult); } return NULL; }
void Acknowledge::send (Message_ptr m) { if (Data const* data = static_cast<Data const*> (m->find (Data::id))) { size_t max_payload_size ( params_.max_packet_size () - max_service_size); if (max_payload_size > data->size ()) { u32 max_size (max_payload_size - data->size ()); u32 max_elem (NRTM::max_count (max_size)); if (max_elem > 0) { Lock l (mutex_); Profile_ptr nrtm (create_nrtm (max_elem)); if (nrtm.get ()) m->add (nrtm); } } nrtm_timer_ = params_.nrtm_timeout (); // Reset timer. } out_->send (m); }
void Socket_Impl:: send_ (void const* buf, size_t s) { Message_ptr m (new Message); m->add (Profile_ptr (new Data (buf, s))); // Qualification is for VC6 and VxWorks. // Element::send (m); }
void Retransmit::send (Message_ptr m) { if (m->find (Data::id) != 0) { SN const* sn = static_cast<SN const*> (m->find (SN::id)); Lock l (mutex_); queue_.bind (sn->num (), Descr (m->clone ())); } out_->send (m); }
ssize_t Socket_Impl:: size_ (ACE_Time_Value const* timeout) { ACE_Time_Value abs_time; if (timeout) abs_time = ACE_OS::gettimeofday () + *timeout; Lock l (mutex_); while (queue_.is_empty ()) { if (timeout) { if (cond_.wait (&abs_time) != -1) break; } else { if (cond_.wait () != -1) break; } return -1; // errno is already set } // I can't get the head of the queue without actually dequeuing // the element. // Message_ptr m; if (queue_.dequeue_head (m) == -1) ACE_OS::abort (); if (queue_.enqueue_head (m) == -1) ACE_OS::abort (); if (m->find (NoData::id) != 0) { errno = ENOENT; return -1; } Data const* d = static_cast<Data const*>(m->find (Data::id)); return static_cast<ssize_t> (d->size ()); }
void Retransmit::recv (Message_ptr m) { if (NAK const* nak = static_cast<NAK const*> (m->find (NAK::id))) { Address to (static_cast<To const*> (m->find (To::id))->address ()); if (nak->address () == to) { Lock l (mutex_); for (NAK::iterator j (const_cast<NAK*> (nak)->begin ()); !j.done (); j.advance ()) { u64* psn; j.next (psn); Message_ptr m; Queue::ENTRY* pair; if (queue_.find (*psn, pair) == 0) { //cerr << 5 << "PRTM " << to << " " << pair->ext_id_ << endl; m = pair->int_id_.message (); pair->int_id_.reset (); } else { //cerr << 4 << "message " << *psn << " not available" << endl; m = Message_ptr (new Message); m->add (Profile_ptr (new SN (*psn))); m->add (Profile_ptr (new NoData)); } out_->send (m); } } } in_->recv (m); }
void Socket_Impl::recv (Message_ptr m) { if (m->find (Data::id) != 0 || m->find (NoData::id) != 0) { if (!loop_) { Address to (static_cast<To const*> (m->find (To::id))->address ()); Address from ( static_cast<From const*> (m->find (From::id))->address ()); if (to == from) return; } Lock l (mutex_); //if (queue_.size () != 0) // cerr << "recv socket queue size: " << queue_.size () << endl; //FUZZ: disable check_for_lack_ACE_OS bool signal (queue_.is_empty ()); //FUZZ: enable check_for_lack_ACE_OS queue_.enqueue_tail (m); if (signal) { // Also write to the pipe. if (signal_pipe_.write_handle () != ACE_INVALID_HANDLE) { char c; if (signal_pipe_.send (&c, 1) != 1) { // perror ("write: "); ACE_OS::abort (); } } cond_.signal (); } } }
void Fragment::send (Message_ptr m) { if (Data const* data = static_cast<Data const*> (m->find (Data::id))) { size_t max_payload_size ( params_.max_packet_size () - max_service_size); if (data->size () <= max_payload_size) { u64 sn; { Lock l (mutex_); sn = sn_++; } m->add (Profile_ptr (new SN (sn))); out_->send (m); return; } char const* p = data->buf (); size_t size (data->size ()); // Need fragmentation. // u32 packets (size / max_payload_size + (size % max_payload_size ? 1 : 0)); // cerr << "size : " << size << endl // << "packs: " << packets << endl; for (u32 i (1); i <= packets; ++i) { Message_ptr part (new Message); size_t s (i == packets ? size % max_payload_size : max_payload_size); // cerr << "pack: " << s << endl; u64 sn; { Lock l (mutex_); sn = sn_++; } part->add (Profile_ptr (new SN (sn))); part->add (Profile_ptr (new Part (i, packets, size))); part->add (Profile_ptr (new Data (p, s))); out_->send (part); p += s; } } }
void MessageProcessorManager::processMessage( Connection_ptr con, Message_ptr msg) { // Obtiene el contenido y el descriptor del mensaje Holder holder = msg->holder(); TypeDescriptor_ptr messageDescriptor = holder.get_type_descriptor(); // creates the key map_t::iterator it = m_processors.find( std::make_pair(con.get(), messageDescriptor)); if (it != m_processors.end() && !it->second.empty()) { // Iterates over its associated processors processors_t::const_iterator pit = it->second.begin(); for (; pit != it->second.end(); ++pit) { const MessageProcessor_ptr processor = *pit; const ReflectivePath_t& path = processor->path(); // Results TypeDescriptor_ptr descriptor = NULL; Holder value; bool res = followPath(messageDescriptor, holder, path, // Results descriptor, value); if (res) processor->process(msg, value); } } }
SendResult_ptr DefaultMQProducerImpl::sendDefaultImpl(Message_ptr msg, std::string& communicationMode, bool sendCallback) { long beginTimestamp = 0; long endTimestamp = beginTimestamp; TopicPublishInfo* topicPublishInfo = this->tryToFindTopicPublishInfo(msg->getTopic()); if (topicPublishInfo->ok()) { MessageQueue* mq = NULL; SendResult_var sendResult = new SendResult(); for (int times = 0; times < 3; times++) { std::string lastBrokerName; if(mq != NULL) { lastBrokerName = mq->getBrokerName(); } MessageQueue* tmpmq = topicPublishInfo->selectOneMessageQueue(lastBrokerName); if (tmpmq != NULL) { mq = tmpmq; sendResult = this->sendKernelImpl(msg, mq, communicationMode, sendCallback); endTimestamp = 12; if(communicationMode == CommunicationMode::SYNC) { if (sendResult->getSendStatus() != SendStatus::SEND_OK) { /* if (this->defaultMQProducer->isRetryAnotherBrokerWhenNotStoreOK()) { continue; } */ } return SendResult_var::Duplicate(sendResult); } } else { break; } } return SendResult_var::Duplicate(sendResult); } return NULL; }
void ProtocolDataWidget::onRecv(Message_ptr m) { Address from; if (From const* f = static_cast<From const*>(m->find(From::id))) { from = f->address(); } if (PFileSend const* pfs = static_cast<PFileSend const*>(m->find(IMProto::FileSend))) { QString const& sn = QString::fromUtf8(pfs->property_data(IMProto::EventSn)); QString const& kName = QString::fromUtf8(pfs->property_data(IMProto::FileKey)); QString const& fName = QString::fromUtf8(pfs->property_data(IMProto::FileName)); quint64 siz = QString::fromUtf8(pfs->property_data(IMProto::FileSize)).toULongLong(); //u16 port = QString::fromUtf8(pfs->property_data(IMProto::ListenPort)).toUShort(); QTreeWidgetItem* root = new QTreeWidgetItem; this->addTopLevelItem(root); m_RecvItemMap.insert(sn, root); QString const& sizstr = GetFormatedFileSize(siz); root->setText(COL_NAME, fName); root->setText(COL_SIZE, sizstr); root->setText(COL_TYPE, tr("File")); root->setText(COL_STATE, tr("waiting to receive")); root->setText(COL_PERCENT, "0%"); root->setData(COL_NAME, FileKeyRole, kName); root->setData(COL_NAME, FileSizeRole, siz); root->setData(COL_NAME, DirFileRole, "FILE"); root->setData(COL_NAME, SendRecvRole, "R"); root->setData(COL_NAME, TransStateRole, "WAIT"); root->setData(COL_NAME, TransItemSNRole, sn); root->setIcon(COL_NAME, QIcon(DataAccess::SkinPath() + "/download-file.png")); root->setIcon(COL_STATE, QIcon(DataAccess::SkinPath() + "/clock.png")); emit sigTips(tr("The other request to send %1:%2. Please switch to file transferring window to process.") .arg(tr("File")) .arg(fName)); } else if (PDirFileRecv const* pfr = static_cast<PDirFileRecv const*>(m->find(IMProto::DirFileRecv))) { QString const& sn = QString::fromUtf8(pfr->property_data(IMProto::EventSn)); QString const& kName = QString::fromUtf8(pfr->property_data(IMProto::FileKey)); u16 port = QString::fromUtf8(pfr->property_data(IMProto::ListenPort)).toUShort(); QTreeWidgetItem* item = m_SendItemMap.value(sn, 0); if (!item) { //QMessageBox::critical(this, tr("Error"), tr("Unable to find item in file SendItemMap. key: %1.").arg(keys[2])); return; } QString const& pfName = m_userItem->SendingFilesCollection()->value(kName); if (pfName.isEmpty()) { //QMessageBox::critical(this, tr("Error"), tr("Unable to find in SendingFilesCollection key: %1.").arg(keys[2])); return; } QFileInfo finfo(pfName); ProtocolDataTransfer* pdthr = 0; if (finfo.isFile()) { pdthr = new ProtocolDataTransfer(item, pfName, 0, port, m_userItem->IpAddress(), ProtocolDataTransfer::DoSendFile); connect(&m_timer, SIGNAL(timeout()), pdthr, SLOT(slotUpdate())); } else if (finfo.isDir()) { pdthr = new ProtocolDataTransfer(item, pfName, port, m_userItem->IpAddress(), ProtocolDataTransfer::DoSendDir); connect(&m_timer, SIGNAL(timeout()), pdthr, SLOT(slotUpdate())); } if (!pdthr) { return; } item->setData(COL_NAME, TransThreadRole, (quint64)pdthr); if (!m_timer.isActive()) { m_timer.start(1000); } pdthr->start(); } else if (ProfileWithProperties const* pds = static_cast<ProfileWithProperties const*>(m->find(IMProto::DirSend))) { QString const& sn = QString::fromUtf8(pds->property_data(IMProto::EventSn)); QString const& kName = QString::fromUtf8(pds->property_data(IMProto::FileKey)); QString const& dName = QString::fromUtf8(pds->property_data(IMProto::FileName)); quint64 siz = QString::fromUtf8(pds->property_data(IMProto::FileSize)).toULongLong(); //u16 port = QString::fromUtf8(pfs->property_data(IMProto::ListenPort)).toUShort(); QTreeWidgetItem* root = new QTreeWidgetItem; this->addTopLevelItem(root); m_RecvItemMap.insert(sn, root); QString const& sizstr = tr("unknown"); root->setText(COL_NAME, dName); root->setText(COL_SIZE, sizstr); root->setText(COL_TYPE, tr("Dir")); root->setText(COL_STATE, tr("waiting to receive")); root->setText(COL_PERCENT, "0%"); root->setData(COL_NAME, FileKeyRole, kName); root->setData(COL_NAME, FileSizeRole, siz); root->setData(COL_NAME, DirFileRole, "DIR"); root->setData(COL_NAME, SendRecvRole, "R"); root->setData(COL_NAME, TransStateRole, "WAIT"); root->setData(COL_NAME, TransItemSNRole, sn); root->setIcon(COL_NAME, QIcon(DataAccess::SkinPath() + "/download-folder.png")); root->setIcon(COL_STATE, QIcon(DataAccess::SkinPath() + "/clock.png")); emit sigTips(tr("The other request to send %1:%2. Please switch to file transferring window to process.") .arg(tr("Dir")) .arg(dName)); } else if (PDirFileSendCancel const* pfsc = static_cast<PDirFileSendCancel const*>(m->find(IMProto::DirFileSendCancel))) { QString const& sn = QString::fromUtf8(pfsc->property_data(IMProto::EventSn)); QTreeWidgetItem* item = m_RecvItemMap.value(sn); if (!item) { //QMessageBox::critical(this, tr("Error"), tr("Unable to find item in file RecvItemMap. key: %1.").arg(keys[2])); return; } QString tips = tr("The other canceled sending %1: %2.").arg(item->text(COL_TYPE)).arg(item->text(COL_NAME)); emit sigTips(tips); m_RecvItemMap.remove(sn); QString const& tsr = item->data(COL_NAME, TransStateRole).toString(); if (tsr == "START") { ProtocolDataTransfer* t = (ProtocolDataTransfer*)item->data(COL_NAME, TransThreadRole).toULongLong(); disconnect(&m_timer, SIGNAL(timeout()), t, SLOT(slotUpdate())); t->slotCancel(); } if (!delItemWhenFinished) { item->setData(COL_NAME, TransStateRole, "CANCEL"); item->setIcon(COL_STATE, QIcon(DataAccess::SkinPath() + "/warning.png")); item->setText(COL_STATE, tr("Canceled")); } else { this->takeTopLevelItem(this->indexOfTopLevelItem(item)); } } else if (ProfileWithProperties const* pfrc = static_cast<ProfileWithProperties const*>(m->find(IMProto::DirFileRecvCancel))) { QString const& sn = QString::fromUtf8(pfrc->property_data(IMProto::EventSn)); QTreeWidgetItem* item = m_SendItemMap.value(sn, 0); if (!item) { //QMessageBox::critical(this, tr("Error"), tr("Unable to find item in file SendItemMap. key: %1.").arg(keys[2])); return; } QString tips = tr("The other canceled receiving %1: %2.").arg(item->text(COL_TYPE)).arg(item->text(COL_NAME)); emit sigTips(tips); m_SendItemMap.remove(sn); QString const& tsr = item->data(COL_NAME, TransStateRole).toString(); if (tsr == "START") { ProtocolDataTransfer* t = (ProtocolDataTransfer*)item->data(COL_NAME, TransThreadRole).toLongLong(); disconnect(&m_timer, SIGNAL(timeout()), t, SLOT(slotUpdate())); t->slotCancel(); } if (!delItemWhenFinished) { item->setData(COL_NAME, TransStateRole, "CANCEL"); item->setIcon(COL_STATE, QIcon(DataAccess::SkinPath() + "/warning.png")); item->setText(COL_STATE, tr("Canceled")); } else { this->takeTopLevelItem(this->indexOfTopLevelItem(item)); } } }
void Acknowledge:: track () { while (true) { Messages msgs; { Lock l (mutex_); if (stop_) break; if (hold_.current_size () != 0) { for (Map::iterator i (hold_.begin ()), e (hold_.end ()); i != e; ++i) { Queue& q = (*i).int_id_; if (q.current_size () == 0) continue; track_queue ((*i).ext_id_, q, msgs); } } if (--nrtm_timer_ == 0) { nrtm_timer_ = params_.nrtm_timeout (); // Send NRTM. // unsigned short max_payload_size ( params_.max_packet_size () - max_service_size); u32 max_elem (NRTM::max_count (max_payload_size)); Profile_ptr nrtm (create_nrtm (max_elem)); if (!nrtm.null ()) { Message_ptr m (new Message); m->add (nrtm); msgs.push_back (m); } } } // Send stuff off. // for (Messages::Iterator i (msgs); !i.done (); i.advance ()) { Message_ptr* ppm; i.next (ppm); //FUZZ: disable check_for_lack_ACE_OS send (*ppm); //FUZZ: enable check_for_lack_ACE_OS } // Go to sleep but watch for "manual cancellation" request. // { //FUZZ: disable check_for_lack_ACE_OS ACE_Time_Value time (ACE_OS::gettimeofday ()); //FUZZ: enable check_for_lack_ACE_OS time += params_.tick (); Lock l (mutex_); while (!stop_) { if (cond_.wait (&time) == -1) { if (errno != ETIME) ACE_OS::abort (); else break; } } if (stop_) break; } } }
void Acknowledge::recv (Message_ptr m) { // Handle NRTM. There could be some nasty interaction with code // that handles data below (like missing message and NAK). This // is why I hold the lock at the beginning (which may be not very // efficient). // Lock l (mutex_); if (NRTM const* nrtm = static_cast<NRTM const*> (m->find (NRTM::id))) { for (Map::iterator i (hold_.begin ()), e (hold_.end ()); i != e; ++i) { u64 sn (nrtm->find ((*i).ext_id_)); if (sn != 0) { Queue& q = (*i).int_id_; u64 old (q.max_sn ()); if (old < sn) { // Mark as lost. // q.bind (sn, Descr (1)); } } } } if (m->find (Data::id) || m->find (NoData::id)) { Address from ( static_cast<From const*> (m->find (From::id))->address ()); u64 sn (static_cast<SN const*> (m->find (SN::id))->num ()); Map::ENTRY* e = 0; if (hold_.find (from, e) == -1) { // First message from this source. // hold_.bind (from, Queue (sn)); in_->recv (m); } else { Queue& q = e->int_id_; if (sn <= q.sn ()) { // Duplicate. // //cerr << 6 << "DUP " << from << " " << q.sn () << " >= " << sn // << endl; } else if (sn == q.sn () + 1) { // Next message. // q.rebind (sn, Descr (m)); collapse (q); } else { // Some messages are missing. Insert this one into the queue. // q.rebind (sn, Descr (m)); } } } else { l.release (); // Just forward it up. // in_->recv (m); } }
void Acknowledge:: track_queue (Address const& addr, Queue& q, Messages& msgs) { unsigned short max_payload_size ( params_.max_packet_size () - max_service_size); u32 max_elem (NAK::max_count (max_payload_size)); u32 count (0); Queue::iterator i (q.begin ()), e (q.end ()); // Track existing losses. // while (i != e) { auto_ptr<NAK> nak (new NAK (addr)); // Inner loop that fills NAK profile with up to max_elem elements. // for (; i != e && nak->count () < max_elem; ++i) { u64 sn ((*i).ext_id_); Descr& d = (*i).int_id_; if (d.lost ()) { d.timer (d.timer () - 1); if (d.timer () == 0) { //@@ Need exp fallback. // d.nak_count (d.nak_count () + 1); d.timer ((d.nak_count () + 1) * params_.nak_timeout ()); nak->add (sn); ++count; // cerr << 6 << "NAK # " << d.nak_count () << ": " // << addr << " " << sn << endl; } } } // Send this NAK. // if (nak->count ()) { // cerr << 5 << "NAK: " << addr << " " << nak->count () << " sns" // << endl; Message_ptr m (new Message); m->add (Profile_ptr (nak.release ())); msgs.push_back (m); } } // Detect and record new losses. // for (u64 sn (q.sn () + 1), end (q.max_sn ()); sn < end; ++sn) { if (q.find (sn) == -1) { q.bind (sn, Descr (1)); } } }
ssize_t Socket_Impl:: recv_ (void* buf, size_t s, ACE_Time_Value const* timeout, ACE_INET_Addr* from) { ACE_Time_Value abs_time; if (timeout) abs_time = ACE_OS::gettimeofday () + *timeout; Lock l (mutex_); while (queue_.is_empty ()) { if (timeout) { if (cond_.wait (&abs_time) != -1) break; } else { if (cond_.wait () != -1) break; } return -1; // errno is already set } Message_ptr m; if (queue_.dequeue_head (m) == -1) ACE_OS::abort (); if (queue_.is_empty ()) { // Remove data from the pipe. // if (signal_pipe_.read_handle () != ACE_INVALID_HANDLE) { char c; if (signal_pipe_.recv (&c, 1) != 1) { ACE_OS::perror ("read: "); ACE_OS::abort (); } } } if (from) *from = static_cast<From const*> (m->find (From::id))->address (); if (m->find (NoData::id) != 0) { errno = ENOENT; return -1; } Data const* d = static_cast<Data const*>(m->find (Data::id)); ssize_t r (static_cast<ssize_t> (d->size () < s ? d->size () : s)); ACE_OS::memcpy (buf, d->buf (), r); return r; }
void Reassemble::recv (Message_ptr m) { Map::ENTRY* e = 0; Address from ( static_cast<From const*> (m->find (From::id))->address ()); if (Data const* data = static_cast<Data const*> (m->find (Data::id))) { if (Part const* part = static_cast<Part const*> (m->find (Part::id))) { if (map_.find (from, e) == -1) { // First part of the message. // if (part->num () != 1) { // We assume that we received NoData for one of the preceding // fragments. Ignore this one. return; } Data_ptr new_data (new Data (data->buf (), static_cast<size_t> (data->size ()), static_cast<size_t> (part->total_size ()))); //std::cerr << "part->total_size (): " << part->total_size () << endl; map_.bind (from, new_data); } else { // Next part of the message. // if (part->num () == 1) ACE_OS::abort (); Data const* data = static_cast<Data const*> (m->find (Data::id)); Data_ptr& new_data = e->int_id_; ACE_OS::memcpy (new_data->buf () + new_data->size (), data->buf (), data->size ()); //std::cerr << "data->size (): " << data->size () << endl // << "new_data->size (): " << new_data->size () << endl // << "new_data->capa (): " << new_data->capacity () << endl; new_data->size (new_data->size () + data->size ()); if (part->num () == part->of ()) { // Reassembly is complete. // if (part->total_size () != new_data->size ()) ACE_OS::abort (); Message_ptr new_msg (new Message ()); Address to ( static_cast<To const*> (m->find (To::id))->address ()); new_msg->add (Profile_ptr (new To (to))); new_msg->add (Profile_ptr (new From (from))); /* * Heads up... we need to add the new_data to new_msg then * unbind the entry that maps to new_data, which will decrement * its reference count. If the bound/refcounted pointer acted * polymorphically like a regular pointer does, we'd be able to * just pass new_data to add(Profile_Ptr) and it would work. * However, Profile_Ptr and Data_Ptr are not compatible, but * we can use the secret knowledge that both are instances of the * same template and that the pointers they contain really are * hierarchically compatible, and do this funky cast to get * the result we want. */ //new_msg->add (*(reinterpret_cast<Profile_ptr*> (&new_data))); new_msg->add (Profile_ptr (new_data)); map_.unbind (from); in_->recv (new_msg); } } } else { // Non-fragmented message. Make sure we are in the consistent state // and forward it up. // if (map_.find (from, e) != -1) ACE_OS::abort (); in_->recv (m); } } else if (m->find (NoData::id) != 0) { if (map_.find (from, e) != -1) { // We already received some fragments. Clean everyhting up. // map_.unbind (from); } in_->recv (m); } }