[8864] | 1 | import datetime |
---|
| 2 | import grok |
---|
| 3 | import os |
---|
| 4 | import time |
---|
| 5 | import zc.async.dispatcher |
---|
| 6 | from cgi import escape |
---|
| 7 | from pytz import utc |
---|
| 8 | from zc.async.interfaces import IQueue |
---|
| 9 | from zc.async.job import Job as AsyncJob |
---|
| 10 | from zc.async.queue import getDefaultQueue |
---|
| 11 | from waeup.kofa.interfaces import IUniversity |
---|
| 12 | from hurry.jqueryui import jqueryui, base, blitzer, ui_lightness, humanity |
---|
| 13 | from hurry.jquery import jquery |
---|
| 14 | from zc.async.interfaces import COMPLETED, NEW, PENDING, ACTIVE, ASSIGNED |
---|
| 15 | |
---|
| 16 | |
---|
| 17 | def compute(num): |
---|
| 18 | start = time.time() |
---|
| 19 | duration = 60 |
---|
| 20 | end = start + duration |
---|
| 21 | print "MyJob starts computation at ", start |
---|
| 22 | #from zc.async.local import getJob, getQueue |
---|
| 23 | myjob = zc.async.local.getJob() |
---|
| 24 | print "MyJob's job: ", zc.async.local.getJob() |
---|
| 25 | print "MyJob's queue: ", zc.async.local.getQueue(), list( |
---|
| 26 | zc.async.local.getQueue()) |
---|
| 27 | while True: |
---|
| 28 | if time.time() > end: |
---|
| 29 | break |
---|
| 30 | time.sleep(1) |
---|
| 31 | percent = (time.time() - start) * 100.0 / duration |
---|
| 32 | if percent > 100.0: |
---|
| 33 | percent = 100.0 |
---|
| 34 | print "MyJob percent: ", percent |
---|
| 35 | zc.async.local.setLiveAnnotation('percent', percent) |
---|
| 36 | print "MyJob does something at %s of %s" % ( |
---|
| 37 | time.time() - start, duration) |
---|
| 38 | print "MyJob's annotations: %r" % dict(myjob.annotations) |
---|
| 39 | print "MyJob's percent: %r" % zc.async.local.getLiveAnnotation( |
---|
| 40 | 'percent') |
---|
| 41 | return num * 2 |
---|
| 42 | |
---|
| 43 | def get_next_num(context): |
---|
| 44 | num = 1 |
---|
| 45 | print "KEYS: ", [x for x in context['jobs'].keys()] |
---|
| 46 | while str(num) in [x for x in context['jobs'].keys()]: |
---|
| 47 | num += 1 |
---|
| 48 | print "NEXT: ", str(num) |
---|
| 49 | return str(num) |
---|
| 50 | |
---|
| 51 | class Job(AsyncJob): |
---|
| 52 | percent = None |
---|
| 53 | pass |
---|
| 54 | |
---|
| 55 | grok.templatedir('.') #os.path.dirname(__file__)) |
---|
| 56 | class ASyncView(grok.View): |
---|
| 57 | grok.context(IUniversity) |
---|
| 58 | grok.name('async') |
---|
| 59 | grok.template('async') |
---|
| 60 | |
---|
| 61 | def update(self, start=None, DELETE=None, REMOVE=None, *args, **kw): |
---|
| 62 | humanity.need() |
---|
| 63 | jqueryui.need() |
---|
| 64 | # the image was created via http://ajaxload.info/ |
---|
| 65 | self.spinner_url = self.url( |
---|
| 66 | grok.getSite()) + '/@@/waeup.kofa.browser/square_circles_black.gif' |
---|
| 67 | print args, kw |
---|
| 68 | self.dispatcher = zc.async.dispatcher.get() |
---|
| 69 | site = grok.getSite() |
---|
| 70 | newq = site.__parent__._p_jar.root()['zc.async'].items()[0][1] |
---|
| 71 | print "NEW: ", newq, list(newq) |
---|
| 72 | |
---|
| 73 | |
---|
| 74 | print "DISP LEN: ", dir(self.dispatcher), self.dispatcher.getStatusInfo(), self.dispatcher.getStatistics(), self.dispatcher.jobs.items() # self.dispatcher.getJobInfo() |
---|
| 75 | self.queue = IQueue(self.context) |
---|
| 76 | self.dispatcher2 = self.queue.dispatchers[zc.async.instanceuuid.UUID] |
---|
| 77 | print "JOBS: ", self.dispatcher.jobs.keys(), self.dispatcher.jobs.values() |
---|
| 78 | print "DISPATCHERS: ", self.dispatcher, self.dispatcher2 |
---|
| 79 | print "QUEUES: ", self.dispatcher.queues |
---|
| 80 | print "QUEUE1: ", list(self.dispatcher.queues['']) |
---|
| 81 | print "QUEUE: ", list(self.queue) |
---|
| 82 | #print "DISPATCHERS: ", self.queue.dispatchers.items() |
---|
| 83 | print "DEFAULT: ", getDefaultQueue(self.context), len(getDefaultQueue(self.context)) |
---|
| 84 | print "DELETE: ", DELETE |
---|
| 85 | if DELETE is not None: |
---|
| 86 | if DELETE in self.context['jobs']: |
---|
| 87 | job = self.context['jobs'][DELETE] |
---|
| 88 | from zc.async.interfaces import COMPLETED, NEW, PENDING |
---|
| 89 | if job.status in (COMPLETED, NEW): |
---|
| 90 | del self.context['jobs'][DELETE] |
---|
| 91 | print "DELETED %s" % job |
---|
| 92 | else: |
---|
| 93 | if job in self.queue: |
---|
| 94 | print "JOB IN ", self.queue, "!!!!!!!!!!!!!!!!!!" |
---|
| 95 | print "QUEUE BEFORE: ", list(self.queue) |
---|
| 96 | try: |
---|
| 97 | self.queue.remove(job) |
---|
| 98 | except: |
---|
| 99 | "COULDN'T REMOVE ANYWAY!!" |
---|
| 100 | print "QUEUE AFTER: ", list(self.queue) |
---|
| 101 | self.queue.pull() |
---|
| 102 | print "QUEUE AFTER2: ", list(self.queue) |
---|
| 103 | #job_queue = job.queue |
---|
| 104 | #agent = job.agent |
---|
| 105 | #print "JOB AGENT: ", agent, dir(agent) |
---|
| 106 | #print "JOB AGENT QUEUE: ", agent.queue, list(agent.queue) |
---|
| 107 | #print "JOB QUEUE: ", job_queue, list(job_queue) |
---|
| 108 | #if job in list(job_queue) or True: |
---|
| 109 | # agent.remove(job) |
---|
| 110 | # #job.queue.remove(job) |
---|
| 111 | # print "REMOVED %s from queue %s" % ( |
---|
| 112 | # job, job_queue) |
---|
| 113 | else: |
---|
| 114 | print "CANT FIND JOB in QUEUE" |
---|
| 115 | |
---|
| 116 | #import pdb; pdb.set_trace() |
---|
| 117 | if start: |
---|
| 118 | start_time = datetime.datetime.utcnow() |
---|
| 119 | start_time += datetime.timedelta(seconds=10) |
---|
| 120 | start_time = utc.localize(start_time) |
---|
| 121 | print "START" |
---|
| 122 | print "STARTTIME: ", start_time |
---|
| 123 | import transaction |
---|
| 124 | transaction.begin() |
---|
| 125 | job = self.queue.put(Job(compute, 21), |
---|
| 126 | begin_after=start_time) |
---|
| 127 | job.annotations['percent'] = 0.0 |
---|
| 128 | print " started: ", job.status, type(job) |
---|
| 129 | if 'jobs' not in self.context: |
---|
| 130 | self.context['jobs'] = grok.Container() |
---|
| 131 | job_id = get_next_num(self.context) |
---|
| 132 | print "JOB ID: ", job_id, dir(job) |
---|
| 133 | self.context['jobs'][job_id] = job |
---|
| 134 | transaction.commit() |
---|
| 135 | time.sleep(0.5) |
---|
| 136 | self.redirect(self.url()) |
---|
| 137 | |
---|
| 138 | def job_status(self): |
---|
| 139 | if 'jobs' not in self.context: |
---|
| 140 | return '' |
---|
| 141 | result = "" |
---|
| 142 | #for num, job in enumerate(self.queue): |
---|
| 143 | for num, job in self.context['jobs'].items(): |
---|
| 144 | result += '<div><form>' |
---|
| 145 | if job.status in ('completed-status', 'new-status'): |
---|
| 146 | result += '<a href="?DELETE=%s">delete</a>' %( |
---|
| 147 | num) |
---|
| 148 | else: # job.status == 'pendig-status' or ( |
---|
| 149 | # job.status == 'active-status'): |
---|
| 150 | result += '<a href="?DELETE=%s">remove from queue</a>' % ( |
---|
| 151 | num) |
---|
| 152 | result += '<input type="checkbox" name="remove" />%s %s, %s, %r</form></div>' % ( |
---|
| 153 | num, |
---|
| 154 | escape('%r' % job), |
---|
| 155 | job.status, |
---|
| 156 | dict(job.annotations)) |
---|
| 157 | print "job in queue: ", job, type(job) |
---|
| 158 | return result |
---|
| 159 | |
---|
| 160 | def NOrender(self): |
---|
| 161 | print "RENDER: ", self.namespace().items(), type(self.namespace) |
---|
| 162 | return grok.PageTemplate('Hallo!') |
---|
| 163 | #print "RENDER: ", self.static['square_circles_black.gif'] |
---|
| 164 | #return r''' |
---|
| 165 | return ''' |
---|
| 166 | <html> |
---|
| 167 | <head> |
---|
| 168 | <title>Async testing</title> |
---|
| 169 | <script type="text/javascript"> |
---|
| 170 | $(document).ready(function() { |
---|
| 171 | var myLoadingDiv = $("#progressbar"); |
---|
| 172 | var mySpinner = $("#loadspinner"); |
---|
| 173 | myLoadingDiv.progressbar({disabled:true}); |
---|
| 174 | function update() { |
---|
| 175 | $.getJSON("status?", {jobid: "4",}, function(data) { |
---|
| 176 | if (data == null) { |
---|
| 177 | myLoadingDiv.progressbar("disable"); |
---|
| 178 | myLoadingDiv.progressbar("value", 0); |
---|
| 179 | $("#msg").html("Syncing..."); |
---|
| 180 | clearInterval(intervalID); |
---|
| 181 | //alert('No Data'): |
---|
| 182 | } |
---|
| 183 | else { |
---|
| 184 | myLoadingDiv.progressbar("enable"); |
---|
| 185 | myLoadingDiv.progressbar("value", data.percent); |
---|
| 186 | $("#msg").html(data.msg + ' (' + data.status + ') '); |
---|
| 187 | //alert(data.msg); |
---|
| 188 | if (data.percent == 100) { |
---|
| 189 | clearInterval(intervalID); |
---|
| 190 | } |
---|
| 191 | } |
---|
| 192 | });} |
---|
| 193 | intervalID = setInterval(update, 500); |
---|
| 194 | //update(); |
---|
| 195 | }); |
---|
| 196 | </script> |
---|
| 197 | </head> |
---|
| 198 | <body> |
---|
| 199 | <h1>Async stuff</h1> |
---|
| 200 | <div>Dispatcher: %s</div> |
---|
| 201 | <div>Queue: %s</div> |
---|
| 202 | <div>Jobs: %s</div> |
---|
| 203 | <form method="POST"> |
---|
| 204 | <input type="submit" name="reload" value="reload" /> |
---|
| 205 | <input type="submit" name="start" value="start up" /> |
---|
| 206 | </form> |
---|
| 207 | <div id="progressbar" |
---|
| 208 | class="ui-progressbar ui-widget ui-widget-content ui-corner-all"> |
---|
| 209 | <div id="msg">Hi there</div> |
---|
| 210 | </div> |
---|
| 211 | <div id="loadspinner"> |
---|
| 212 | </div> |
---|
| 213 | </body> |
---|
| 214 | </htlm> |
---|
| 215 | ''' % ( |
---|
| 216 | escape('%r' % self.dispatcher), |
---|
| 217 | escape('%r' % self.queue), |
---|
| 218 | self.job_status(), |
---|
| 219 | ) |
---|
| 220 | |
---|
| 221 | |
---|
| 222 | class ASyncJSON(grok.JSON): |
---|
| 223 | grok.context(IUniversity) |
---|
| 224 | |
---|
| 225 | def status(self, jobid): |
---|
| 226 | print "request for ", jobid |
---|
| 227 | msg = 'please wait...' |
---|
| 228 | job = self.context['jobs'].get(jobid, None) |
---|
| 229 | if not job: |
---|
| 230 | return |
---|
| 231 | percent = job.annotations.get('percent', None) |
---|
| 232 | if not percent: |
---|
| 233 | return |
---|
| 234 | percent = int(percent+0.5) |
---|
| 235 | print "percent: ", percent |
---|
| 236 | if percent >= 100: |
---|
| 237 | percent = 100 |
---|
| 238 | msg = 'done.' |
---|
| 239 | status_map = { |
---|
| 240 | NEW: 'new', |
---|
| 241 | COMPLETED: 'completed', |
---|
| 242 | PENDING: 'pending', |
---|
| 243 | ACTIVE: 'active', |
---|
| 244 | ASSIGNED: 'assigned', |
---|
| 245 | } |
---|
| 246 | return {'msg': msg, |
---|
| 247 | 'percent': percent, |
---|
| 248 | 'status': status_map.get(job.status, 'unknown'), |
---|
| 249 | } |
---|