source: sage/dsage/database/monitordb.py @ 4353:ed964f1d9d30

Revision 4353:ed964f1d9d30, 8.4 KB checked in by Yi Qiang <yqiang@…>, 6 years ago (diff)

Commit for inclusion in sage-2.5.

Line 
1##############################################################################
2#                                                                     
3#  DSAGE: Distributed SAGE                     
4#                                                                             
5#       Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com>               
6#                                                                           
7#  Distributed under the terms of the GNU General Public License (GPL)       
8#
9#    This code is distributed in the hope that it will be useful,
10#    but WITHOUT ANY WARRANTY; without even the implied warranty of
11#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12#    General Public License for more details.
13#
14#  The full text of the GPL is available at:
15#
16#                  http://www.gnu.org/licenses/
17#
18##############################################################################
19
20import datetime
21import os
22import sqlite3
23
24from twisted.python import log
25
26import sage.dsage.database.sql_functions as sql_functions
27from sage.dsage.misc.config import get_conf
28
29class MonitorDatabase(object):
30    """
31    This table keeps track of workers.
32   
33    """
34       
35    CREATE_MONITOR_TABLE = """CREATE TABLE monitors
36    (
37     uuid text NOT NULL UNIQUE,
38     hostname TEXT,
39     ip TEXT,
40     workers INTEGER,
41     sage_version text,
42     os text,
43     kernel_version TEXT,
44     cpus INTEGER,
45     cpu_speed INTEGER,
46     cpu_model TEXT,
47     mem_total INTEGER,
48     mem_free INTEGER,
49     connected BOOL,
50     busy BOOL,
51     anonymous BOOL DEFAULT 0,
52     last_connection timestamp
53    )
54    """
55   
56    def __init__(self, test=False):
57        self.tablename = 'monitors'
58        if test:
59            self.db_file = 'monitordb_test.db'
60            self.log_level = 5
61            self.log_file = 'monitordb_test.log'
62        else:
63            self.conf = get_conf(type='monitordb')
64            self.db_file = self.conf['db_file']
65            if not os.path.exists(self.db_file):
66                dir, file = os.path.split(self.db_file)
67                if not os.path.isdir(dir):
68                    os.mkdir(dir)
69            self.log_level = self.conf['log_level']
70            self.log_file = self.conf['log_file']
71        self.con = sqlite3.connect(self.db_file,
72                isolation_level=None,
73                detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
74        sql_functions.optimize_sqlite(self.con)
75        # Don't use this, it's slow!
76        # self.con.text_factory = sqlite3.OptimizedUnicode
77        self.con.text_factory = str
78       
79        if sql_functions.table_exists(self.con, self.tablename) is None:
80            sql_functions.create_table(self.con, 
81                                       self.tablename,
82                                       self.CREATE_MONITOR_TABLE)
83            self.con.commit()
84       
85    def _set_parameter(self, uuid, key, value):
86        query = """UPDATE monitors
87        SET %s=?
88        WHERE uuid=?""" % (key)
89        cur = self.con.cursor()
90        cur.execute(query, (value, uuid))
91        self.con.commit()
92   
93    def set_anonymous(self, uuid, anonymous=True):
94        return self._set_parameter(uuid, 'anonymous', anonymous)
95       
96    def add_monitor(self, host_info):
97        query = """INSERT INTO monitors
98        (uuid,
99         hostname,
100         ip,
101         workers,
102         sage_version,
103         os,
104         kernel_version,
105         cpus,
106         cpu_speed,
107         cpu_model,
108         mem_total,
109         mem_free)
110        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
111        """
112       
113        uuid = host_info['uuid']
114        hostname = host_info['hostname']
115        ip = host_info['ip']
116        workers = host_info['workers']
117        sage_version = host_info['sage_version']
118        os = host_info['os']
119        kernel_version = host_info['kernel_version']
120        cpus = host_info['cpus']
121        cpu_speed = host_info['cpu_speed']
122        cpu_model = host_info['cpu_model']
123        mem_total = host_info['mem_total']
124        mem_free = host_info['mem_free']
125       
126        cur = self.con.cursor()
127        cur.execute(query, (uuid, hostname, ip, workers, sage_version, os, 
128                            kernel_version, cpus, cpu_speed, cpu_model,
129                            mem_total, mem_free))
130        self.con.commit()
131   
132    def get_monitor(self, uuid):
133        query = """SELECT uuid, hostname, ip, anonymous, sage_version, os FROM monitors
134        WHERE uuid=?"""
135        cur = self.con.cursor()
136        cur.execute(query, (uuid,))
137        result = cur.fetchone()
138        if result is None:
139            return result
140        columns = [desc[0] for desc in cur.description]
141        monitor = dict(zip(columns, result))
142        for k, v in monitor.iteritems():
143            if k == 'anonymous':
144                monitor[k] = bool(v)
145               
146        return monitor
147
148    def get_monitor_list(self):
149        """
150        Returns a list of connected monitors.
151       
152        """
153       
154        query = """SELECT uuid, hostname, ip, anonymous, sage_version, os FROM monitors
155        WHERE connected"""
156        cur = self.con.cursor()
157        cur.execute(query)
158        result = cur.fetchall()
159        columns = [desc[0] for desc in cur.description]
160        monitors = [dict(zip(columns, monitor)) for monitor in result]
161        for monitor in monitors:
162            for k, v in monitor.iteritems():
163                if k == 'anonymous':
164                    monitor[k] = bool(v)
165                   
166        return monitors
167       
168    def set_connected(self, uuid, connected=True):
169        """
170        Sets the connected status of a worker.
171       
172        Parameters:
173        uuid -- string
174        connected -- bool
175       
176        """
177       
178        cur = self.con.cursor()
179        if connected:
180            query = """UPDATE monitors SET connected=1, last_connection=?
181            WHERE uuid=?"""
182            cur.execute(query, (datetime.datetime.now(), uuid))
183        else:
184            query = """UPDATE monitors SET connected=0 WHERE uuid=?"""
185            cur.execute(query, (uuid,))
186           
187        self.con.commit()
188   
189    def set_busy(self, uuid, busy):
190        """
191        Sets whether or not a worker is doing a job.
192       
193        """
194       
195        if busy:
196            query = """UPDATE monitors SET busy=1 WHERE uuid=?"""
197        else:
198            query = """UPDATE monitors SET busy=0 WHERE uuid=?"""
199       
200        cur = self.con.cursor()
201        cur.execute(query, (uuid,))
202        self.con.commit()
203       
204    def get_worker_count(self, connected, busy):
205        """
206        Returns the number of workers.
207       
208        Parameters:
209        connected -- bool
210        busy -- bool
211       
212        """
213       
214        if connected and not busy:
215            query = """SELECT workers FROM monitors WHERE connected AND NOT busy"""
216        elif connected and busy:
217            query = """SELECT workers FROM monitors WHERE connected AND busy"""
218        elif connected:
219            query = """SELECT workers FROM monitors WHERE connected"""
220        else:
221            query = "SELECT workers FROM monitors WHERE NOT connected"
222       
223        cur = self.con.cursor()
224        cur.execute(query)
225        result = cur.fetchall()
226       
227        return sum(w[0] for w in result)
228
229    def get_cpu_speed(self, connected=True, busy=True):
230        """
231        Returns the aggregate cpu speed in Mhz.
232       
233        Parameters:
234        connected -- bool
235       
236        """
237       
238        if connected:
239            query = """SELECT cpu_speed, workers FROM monitors
240            WHERE connected AND busy"""
241        else:
242            query = """SELECT cpu_speed, workers FROM monitors"""
243           
244        cur = self.con.cursor()
245        cur.execute(query)
246       
247        result = cur.fetchall()
248       
249        cpu_speed = sum([s[0]*s[1] for s in result])
250       
251        return cpu_speed
252   
253    def get_cpu_count(self, connected=True):
254        """
255        Returns the number of cpus that are available.
256       
257        Parameters:
258        connected -- bool
259       
260        """
261       
262        if connected:
263            query = """SELECT workers, cpus FROM monitors WHERE connected"""
264        else:
265            query = """SELECT workers, cpus FROM monitors"""
266       
267        cur = self.con.cursor()
268        cur.execute(query)
269       
270        result = cur.fetchall()
271       
272        cpu_count = sum(min(s[0:2]) for s in result)
273       
274        return cpu_count
Note: See TracBrowser for help on using the repository browser.