void IRCDProto::SendMessage(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...) { va_list args; char buf[BUFSIZE] = ""; va_start(args, fmt); vsnprintf(buf, BUFSIZE - 1, fmt, args); va_end(args); SendMessageInternal(bi, dest, buf); }
// LookForWorkers //------------------------------------------------------------------------------ void Client::LookForWorkers() { PROFILE_FUNCTION MutexHolder mh( m_ServerListMutex ); const size_t numWorkers( m_ServerList.GetSize() ); // find out how many connections we have now size_t numConnections = 0; for ( size_t i=0; i<numWorkers; i++ ) { if ( m_ServerList[ i ].m_Connection ) { numConnections++; } } // limit maximum concurrent connections if ( numConnections >= m_WorkerConnectionLimit ) { return; } // if we're connected to every possible worker already if ( numConnections == numWorkers ) { return; } // randomize the start index to better distribute workers when there // are many workers/clients - otherwise all clients will attempt to connect // to the same subset of workers Random r; size_t startIndex = r.GetRandIndex( (uint32_t)numWorkers ); // find someone to connect to for ( size_t j=0; j<numWorkers; j++ ) { const size_t i( ( j + startIndex ) % numWorkers ); ServerState & ss = m_ServerList[ i ]; if ( ss.m_Connection ) { continue; } // ignore blacklisted workers if ( ss.m_Blacklisted ) { continue; } // lock the server state MutexHolder mhSS( ss.m_Mutex ); ASSERT( ss.m_Jobs.IsEmpty() ); if ( ss.m_DelayTimer.GetElapsed() < CONNECTION_REATTEMPT_DELAY_TIME ) { continue; } const ConnectionInfo * ci = Connect( m_WorkerList[ i ], m_Port, 2000 ); // 2000ms connection timeout if ( ci == nullptr ) { ss.m_DelayTimer.Start(); // reset connection attempt delay } else { DIST_INFO( "Connected: %s\n", m_WorkerList[ i ].Get() ); const uint32_t numJobsAvailable( JobQueue::IsValid() ? (uint32_t)JobQueue::Get().GetNumDistributableJobsAvailable() : 0 ); ci->SetUserData( &ss ); ss.m_RemoteName = m_WorkerList[ i ]; ss.m_Connection = ci; // success! ss.m_NumJobsAvailable = numJobsAvailable; ss.m_StatusTimer.Start(); // send connection msg Protocol::MsgConnection msg( numJobsAvailable ); SendMessageInternal( ci, msg ); } // limit to one connection attempt per iteration return; } }