You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
5.0 KiB
210 lines
5.0 KiB
/*
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) version 2.
|
|
*/
|
|
|
|
/*
|
|
Copyright (C) 2008 Eli J. MacKenzie <argonel at gmail.com>
|
|
*/
|
|
|
|
#include <tqdatetime.h>
|
|
#include <tqtimer.h>
|
|
#include <tqstring.h>
|
|
|
|
#include "ircqueue.h"
|
|
#include "server.h"
|
|
|
|
//#include "/home/ejm/argnl.h"
|
|
|
|
IRCQueue::EmptyingRate staticrates[Server::Howmanyqueuesdoweneedanywayquestionmark]; /*=
|
|
{
|
|
IRCQueue::EmptyingRate(6,60000)
|
|
,IRCQueue::EmptyingRate(20,60000)
|
|
,IRCQueue::EmptyingRate(1,1000)//,IRCQueue::EmptyingRate::Bytes)
|
|
};
|
|
*/
|
|
|
|
int IRCQueue::EmptyingRate::nextInterval(int, int elapsed)
|
|
{
|
|
if (!isValid())
|
|
return 0;
|
|
//KX << _S(m_interval) << endl;
|
|
if (m_type == Lines)
|
|
{
|
|
int i = m_interval/m_rate;
|
|
//KX << _S(i) << endl;
|
|
if (i<elapsed) {
|
|
//KX << _S(i) << _S(elapsed) << endl;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
//KX << _S(i) << endl;
|
|
return i;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//TODO write this...
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
IRCQueue::EmptyingRate& IRCQueue::getRate()
|
|
{
|
|
return m_rate;
|
|
}
|
|
|
|
|
|
IRCQueue::IRCQueue(Server *server, EmptyingRate& rate, int ind) :
|
|
m_rate(rate), m_blocked(true), m_server(server),
|
|
m_linesSent(0), m_globalLinesSent(0),
|
|
m_bytesSent(0), m_globalBytesSent(0), m_lastWait(0), m_myIndex(ind)
|
|
{
|
|
//KX << _S(m_rate.m_rate) << _S(m_rate.m_interval) << _S(m_rate.m_type) << endl;
|
|
m_timer=new TQTimer(this);
|
|
connect(m_timer, TQ_SIGNAL(timeout()), TQ_SLOT(sendNow()));
|
|
if (server)
|
|
{
|
|
connect(server, TQ_SIGNAL(serverOnline(bool)), TQ_SLOT(serverOnline(bool)));
|
|
connect(server, TQ_SIGNAL(sentStat(int, int, IRCQueue*)), TQ_SLOT(sent(int, int, IRCQueue*)));
|
|
m_blocked=!(m_server->isConnected());
|
|
}
|
|
}
|
|
|
|
IRCQueue::~IRCQueue()
|
|
{
|
|
kdDebug() << "~IRCQueue" << endl;
|
|
}
|
|
|
|
TQString IRCQueue::pop()
|
|
{
|
|
if (m_pending.isEmpty())
|
|
return TQString("");
|
|
|
|
IRCMessage msg=m_pending.first();
|
|
m_pending.pop_front();
|
|
m_lastWait=msg.age();
|
|
m_lastSent=TQTime::currentTime();
|
|
return msg.text();
|
|
}
|
|
|
|
int IRCQueue::nextSize()
|
|
{
|
|
if (m_pending.isEmpty())
|
|
return 0;
|
|
return m_pending.first().text().length();
|
|
}
|
|
|
|
int IRCQueue::currentWait()
|
|
{
|
|
if (m_pending.isEmpty())
|
|
return 0;
|
|
return m_pending.first().age();
|
|
}
|
|
|
|
int IRCQueue::elapsed()
|
|
{
|
|
if (m_startedAt.isNull())
|
|
return 0;
|
|
else
|
|
return m_startedAt.elapsed(); //FIXME if its been more than a day since this queue was used, this breaks
|
|
}
|
|
|
|
int IRCQueue::linesSent() const
|
|
{
|
|
return m_linesSent;
|
|
}
|
|
|
|
int IRCQueue::bytesSent() const
|
|
{
|
|
return m_bytesSent;
|
|
}
|
|
|
|
///Feedback indicating size of data sent to update statistics. Not necessarily data from this queue!!!
|
|
void IRCQueue::sent(int, int e, IRCQueue *wq)
|
|
{
|
|
//KX << k_funcinfo << _S(m_mine) << endl;
|
|
m_globalLinesSent++;
|
|
m_globalBytesSent+=e; // we don't care about the unencoded bytes, we want what went to the server
|
|
if (wq == this) {
|
|
m_linesSent++;
|
|
m_bytesSent+=e;
|
|
}
|
|
}
|
|
|
|
void IRCQueue::enqueue(TQString line)
|
|
{
|
|
m_pending.append(IRCMessage(line));
|
|
if (!m_timer->isActive())
|
|
adjustTimer();
|
|
}
|
|
|
|
//starts timer if stopped, adjusts interval if necessary
|
|
void IRCQueue::adjustTimer()
|
|
{
|
|
int msec;
|
|
msec=getRate().nextInterval(nextSize(), elapsed());
|
|
//if (m_myIndex == 0)
|
|
// KX << _S(msec) << endl;
|
|
m_timer->start(msec,true);
|
|
m_startedAt.start();
|
|
return;
|
|
}
|
|
|
|
bool IRCQueue::doSend()
|
|
{
|
|
bool p=!m_pending.isEmpty();
|
|
if (p)
|
|
{
|
|
// int plw = m_lastWait;
|
|
TQString s=pop();
|
|
//if (m_myIndex == 0)
|
|
// KX << _S(plw) << _S(m_lastWait) << endl;
|
|
m_server->toServer(s, this);
|
|
m_startedAt.start();
|
|
}
|
|
return p;//if we sent something, fire the timer again
|
|
}
|
|
|
|
///it would probably be better to delete and recreate the queue.
|
|
void IRCQueue::reset()
|
|
{
|
|
// KX << k_funcinfo << endl;
|
|
m_timer->stop();
|
|
m_lastWait=0;
|
|
if (m_server)
|
|
m_blocked=!(m_server->isConnected()); //FIXME (maybe) "we can't do this anymore because blocked can't correspond to whether the server is online, instead must correspond to whether the socket has become writable (readyWrite)"
|
|
|
|
m_startedAt=m_globalLastSent=m_lastSent=TQTime();
|
|
m_pending.clear();
|
|
m_linesSent=m_bytesSent=m_globalBytesSent=m_globalLinesSent=0;
|
|
}
|
|
|
|
//called when the timer fires.
|
|
void IRCQueue::sendNow()
|
|
{
|
|
if (doSend())
|
|
adjustTimer();
|
|
//else //its a single-shot timer so if we don't adjust it, it won't run :)
|
|
}
|
|
|
|
///lets us know we should block output
|
|
void IRCQueue::serverOnline(bool on)
|
|
{
|
|
if (m_blocked!=on)
|
|
return;
|
|
m_blocked=!on;
|
|
if (m_blocked && m_timer->isActive())
|
|
reset();
|
|
else if (!m_blocked && !m_timer->isActive() && nextSize())
|
|
{
|
|
adjustTimer();
|
|
}
|
|
}
|
|
|
|
#include "ircqueue.moc"
|