Esempio n. 1
0
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);
}
Esempio n. 2
0
// 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;
    }
}