rendered paste body#!/usr/bin/env pythonimport sysimport osimport timeimport cPicklefrom optparse import OptionParserfrom twisted.internet import reactorfrom twisted.web import xmlrpcfrom twisted.web import serverfrom twisted.web import resourcefrom twisted.spread import pbfrom twisted.python import logfrom twisted.cred import checkers, portalfrom zope.interface import implementsfrom job_database import JobDatabasefrom job import Job# This class is needed to be able to send our Job class over Perspective Brokerclass ReceiverJob(pb.RemoteCopy, Job): passpb.setUnjellyableForClass(Job, ReceiverJob)class dsaged(pb.Root): def __init__(self, jobdb): """Initializes the XMLRPC Server. Parameters: jobdb -- pass in the Database object """ # start our logging facility # log.startLogging(open('distributed_sage.log', 'a')) log.startLogging(sys.stdout) self.jobdb = jobdb def get_job(self, n): """Returns a list of job(s) dictionaries to the client. Parameters: n -- number of jobs, default = 1 """ print "Someone is getting %s job(s)!" % (str(n)) jobs = self.jobdb.get_active_jobs(n=n) print type(jobs) if jobs == None: return ['2**100'] return jobs def submit_job(self, job): """Submits a Job""" print "[dsaged] Someone submitted a job: %s" % (job) return self.jobdb.submit_job(job) def get_job_list(self): pass def show_active_jobs(self): """Returns a list of active jobs""" return self.jobdb.list_active_jobs() def show_active_clients(self): """Returns a list of active clients""" pass def log_msg(self, msg): """Logs message to distributed_sage.log Parameters: msg -- string to log """ if isinstance(msg) != str: msg = str(msg) log.msg(msg)class UserPerspective(pb.Avatar): def __init__(self, dsaged): self.dsaged = dsaged def perspective_get_job(self, n): return self.dsaged.get_job(n)class AdminPerspective(UserPerspective): def __init__(self, dsaged): self.dsaged = dsaged print "admin connected" def perspective_submit_job(self, Job): return self.dsaged.submit_job(Job)class Realm(object): implements(portal.IRealm) def __init__(self, dsaged): self.dsaged = dsaged def requestAvatar(self, avatarId, mind, *interfaces): if not pb.IPerspective in interfaces: raise NotImplementedError, "No supported avatar interface." else: if avatarId == 'admin': avatar = AdminPerspective(self.dsaged) else: avatar = UserPerspective(self.dsaged) return pb.IPerspective, avatar, lambda: Nonedef usage(): """Prints usage help.""" # usage options usage = ['usage: %progr [options]\n', 'required options: --jobdir\n\n', 'Bug reports to <yqiang@gmail.com>'] parser = OptionParser(usage=''.join(usage)) parser.add_option("-j", "--jobdir", dest="dir", help="directory containing jobs") (options, args) = parser.parse_args() if options.dir == None: parser.print_help() sys.exit(0) parser.error("Please specify a valid job directory with the --jobdir flag.") sys.path.append(os.path.abspath(options.dir)) return optionsdef main(): """Main execution loop of the server.""" options = usage() jobdb = JobDatabase('distributed_sage.db') p = portal.Portal(Realm(dsaged(jobdb))) p.registerChecker(checkers.OnDiskUsernamePasswordDatabase('user_database.db')) reactor.listenTCP(8082, pb.PBServerFactory(p)) reactor.run()if __name__ == "__main__": main()