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.
konversation/konversation/src/ircqueue.cpp

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"