2
This file is part of Icecream.
4
Copyright (c) 2003 Frerich Raabe <raabe@kde.org>
5
Copyright (c) 2003,2004 Stephan Kulow <coolo@kde.org>
6
Copyright (c) 2003,2004 Cornelius Schumacher <schumacher@kde.org>
7
Copyright (c) 2007 Dirk Mueller <mueller@kde.org>
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
#include "icecreammonitor.h"
27
#include "statusview.h"
29
#include <icecc/comm.h>
33
#include <qsocketnotifier.h>
41
IcecreamMonitor::IcecreamMonitor( HostInfoManager *manager, QObject *parent)
42
: Monitor(manager, parent)
44
, m_schedulerState( false )
47
, m_fd_type(QSocketNotifier::Exception)
52
IcecreamMonitor::~IcecreamMonitor()
58
void IcecreamMonitor::checkScheduler(bool deleteit)
60
qDebug() << "checkScheduler " << deleteit << endl;
62
m_rememberedJobs.clear();
67
m_fd_type = QSocketNotifier::Exception;
70
setSchedulerState(false);
71
} else if ( m_scheduler )
73
QTimer::singleShot( 1000+(qrand()&1023), this, SLOT( slotCheckScheduler() ) ); // TODO: check if correct
76
void IcecreamMonitor::registerNotify(int fd, QSocketNotifier::Type type, const char* slot)
79
m_fd_notify->disconnect(this);
80
m_fd_notify->deleteLater();
82
m_fd_notify = new QSocketNotifier(fd, type, this);
84
QObject::connect(m_fd_notify, SIGNAL(activated(int)), slot);
87
void IcecreamMonitor::slotCheckScheduler()
94
if ( !m_current_netname.isEmpty() )
95
names.push_front( m_current_netname.data() );
97
names.push_front("ICECREAM");
99
if (!qgetenv("USE_SCHEDULER").isEmpty())
100
names.push_front(""); // try $USE_SCHEDULER
102
for ( list<string>::const_iterator it = names.begin(); it != names.end();
105
m_current_netname = it->c_str();
107
|| m_discover->timed_out()) {
109
m_discover = new DiscoverSched ( m_current_netname.data() );
112
m_scheduler = m_discover->try_get_scheduler ();
115
hostInfoManager()->setSchedulerName( QString::fromLatin1(m_discover->schedulerName().data()) );
116
hostInfoManager()->setNetworkName( QString::fromLatin1(m_discover->networkName().data()) );
117
m_scheduler->setBulkTransfer();
120
registerNotify(m_scheduler->fd,
121
QSocketNotifier::Read, SLOT(msgReceived()));
123
if ( !m_scheduler->send_msg ( MonLoginMsg() ) ) {
124
checkScheduler(true);
125
QTimer::singleShot(0, this, SLOT(slotCheckScheduler()));
128
setSchedulerState( true );
133
if (m_fd_type != QSocketNotifier::Write
134
&& m_discover->connect_fd() >= 0) {
135
registerNotify(m_discover->connect_fd(),
136
QSocketNotifier::Write, SLOT(slotCheckScheduler()));
139
else if (m_fd_type != QSocketNotifier::Read
140
&& m_discover->listen_fd() >= 0) {
141
registerNotify(m_discover->listen_fd(),
142
QSocketNotifier::Read, SLOT(slotCheckScheduler()));
144
if (m_fd_type == QSocketNotifier::Read)
145
QTimer::singleShot(1000+(qrand()&1023), this, SLOT(slotCheckScheduler()));
148
setSchedulerState( false );
151
void IcecreamMonitor::msgReceived()
153
while (!m_scheduler->read_a_bit() || m_scheduler->has_msg())
154
if (!handle_activity())
158
bool IcecreamMonitor::handle_activity()
160
Msg *m = m_scheduler->get_msg ();
162
qDebug() << "lost connection to scheduler\n";
163
checkScheduler( true );
164
setSchedulerState( false );
172
case M_MON_JOB_BEGIN:
173
handle_job_begin( m );
176
handle_job_done( m );
179
std::cout << "END" << endl;
180
checkScheduler( true );
185
case M_MON_LOCAL_JOB_BEGIN:
186
handle_local_begin( m );
188
case M_JOB_LOCAL_DONE:
189
handle_local_done( m );
192
cout << "UNKNOWN" << endl;
199
void IcecreamMonitor::handle_getcs( Msg *_m )
201
MonGetCSMsg *m = dynamic_cast<MonGetCSMsg*>( _m );
203
m_rememberedJobs[m->job_id] = Job( m->job_id, m->clientid,
205
m->lang == CompileJob::Lang_C ? "C" :
207
m_view->update( m_rememberedJobs[m->job_id] );
210
void IcecreamMonitor::handle_local_begin( Msg *_m )
212
MonLocalJobBeginMsg *m = dynamic_cast<MonLocalJobBeginMsg*>( _m );
215
m_rememberedJobs[m->job_id] = Job( m->job_id, m->hostid,
218
m_rememberedJobs[m->job_id].setState( Job::LocalOnly );
219
m_view->update( m_rememberedJobs[m->job_id] );
222
void IcecreamMonitor::handle_local_done( Msg *_m )
224
JobLocalDoneMsg *m = dynamic_cast<JobLocalDoneMsg*>( _m );
227
JobList::iterator it = m_rememberedJobs.find( m->job_id );
228
if ( it == m_rememberedJobs.end() ) {
229
// we started in between
233
( *it ).setState( Job::Finished );
234
m_view->update( *it );
236
if ( m_rememberedJobs.size() > 3000 ) { // now remove 1000
240
m_rememberedJobs.erase( m_rememberedJobs.begin() );
244
void IcecreamMonitor::handle_stats( Msg *_m )
246
MonStatsMsg *m = dynamic_cast<MonStatsMsg*>( _m );
249
QStringList statmsg = QString( m->statmsg.c_str() ).split( '\n' );
250
HostInfo::StatsMap stats;
251
for ( QStringList::ConstIterator it = statmsg.constBegin(); it != statmsg.constEnd();
254
key = key.left( key.indexOf( ':' ) );
256
value = value.mid( value.indexOf( ':' ) + 1 );
260
HostInfo *hostInfo = hostInfoManager()->checkNode( m->hostid, stats );
262
if ( hostInfo->isOffline() ) {
263
m_view->removeNode( m->hostid );
265
m_view->checkNode( m->hostid );
269
void IcecreamMonitor::handle_job_begin( Msg *_m )
271
MonJobBeginMsg *m = dynamic_cast<MonJobBeginMsg*>( _m );
274
JobList::iterator it = m_rememberedJobs.find( m->job_id );
275
if ( it == m_rememberedJobs.end() ) {
276
// we started in between
280
( *it ).setServer( m->hostid );
281
( *it ).setStartTime( m->stime );
282
( *it ).setState( Job::Compiling );
285
qDebug() << "BEGIN: " << (*it).fileName() << " (" << (*it).jobId()
289
m_view->update( *it );
292
void IcecreamMonitor::handle_job_done( Msg *_m )
294
MonJobDoneMsg *m = dynamic_cast<MonJobDoneMsg*>( _m );
297
JobList::iterator it = m_rememberedJobs.find( m->job_id );
298
if ( it == m_rememberedJobs.end() ) {
299
// we started in between
303
( *it ).exitcode = m->exitcode;
305
( *it ).setState( Job::Failed );
307
( *it ).setState( Job::Finished );
308
( *it ).real_msec = m->real_msec;
309
( *it ).user_msec = m->user_msec;
310
( *it ).sys_msec = m->sys_msec; /* system time used */
311
( *it ).pfaults = m->pfaults; /* page faults */
313
( *it ).in_compressed = m->in_compressed;
314
( *it ).in_uncompressed = m->in_uncompressed;
315
( *it ).out_compressed = m->out_compressed;
316
( *it ).out_uncompressed = m->out_uncompressed;
320
qDebug() << "DONE: " << (*it).fileName() << " (" << (*it).jobId()
324
m_view->update( *it );
327
void IcecreamMonitor::setCurrentView( StatusView *view, bool rememberJobs )
331
m_view->updateSchedulerState( m_schedulerState );
333
if ( rememberJobs ) {
334
JobList::ConstIterator it = m_rememberedJobs.constBegin();
335
for ( ; it != m_rememberedJobs.constEnd(); ++it )
336
m_view->update( *it );
340
void IcecreamMonitor::setCurrentNet( const QByteArray &netName )
342
m_current_netname = netName;
345
void IcecreamMonitor::setSchedulerState( bool online )
347
if (m_schedulerState == online)
349
m_schedulerState = online;
350
emit schedulerStateChanged( online );
351
m_view->updateSchedulerState( online );
354
#include "icecreammonitor.moc"