[3570545] | 1 | # This program is public domain |
---|
| 2 | """ |
---|
| 3 | Interface to the PARK fitting service. |
---|
| 4 | |
---|
| 5 | *** WARNING *** This is a design sketch and is not presently used. |
---|
| 6 | """ |
---|
| 7 | |
---|
| 8 | class FitClient(object): |
---|
| 9 | """ |
---|
| 10 | Client-side view of the fitting service. |
---|
| 11 | """ |
---|
| 12 | def __init__(self, url=DEFAULT_URL,user=DEFAULT_USER): |
---|
| 13 | self.url = url |
---|
| 14 | self.user = user |
---|
| 15 | self.server = xmlrpclib.Server(self.server) |
---|
| 16 | self.context = self.server.welcome(self.user) |
---|
| 17 | |
---|
| 18 | # User management |
---|
| 19 | def notify(self,email=None,rate=None): |
---|
| 20 | """Set the email address and update frequency for user notification""" |
---|
| 21 | if email is not None: |
---|
| 22 | self.server.setemail(self.context, email) |
---|
| 23 | if rate is not None: |
---|
| 24 | self.server.setrate(self.context, rate) |
---|
| 25 | |
---|
| 26 | # Job management |
---|
| 27 | def find_by_name(self, name): |
---|
| 28 | return self.server.find_by_name(self.context,status) |
---|
| 29 | def find_jobs(self,status='active'): |
---|
| 30 | """List active and recently completed jobs""" |
---|
| 31 | return self.server.find_jobs(self.context,status) |
---|
| 32 | def stop(self, jobid): |
---|
| 33 | """Delete job""" |
---|
| 34 | self.server.delete(self.context, jobid) |
---|
| 35 | def start(self, job): |
---|
| 36 | s = encode(job) |
---|
| 37 | return self.server.submit(self.context, jobname, job) |
---|
| 38 | def fetch_job(self, jobid): |
---|
| 39 | """Retrieve job""" |
---|
| 40 | text = self.server.retrieve(self.context, jobid) |
---|
| 41 | return encode(text) |
---|
| 42 | def status(self, jobid): |
---|
| 43 | """Return the current job status""" |
---|
| 44 | return self.server.status(self.context, jobid) |
---|
| 45 | |
---|
| 46 | # Message Queue |
---|
| 47 | def _listener(self, callback): |
---|
| 48 | while True: |
---|
| 49 | message = self.server.next_message(self.user) |
---|
| 50 | event,result = pickle.loads(text) |
---|
| 51 | callback(event, self, result) |
---|
| 52 | |
---|
| 53 | def listen(self, callback=on_message): |
---|
| 54 | """ |
---|
| 55 | Listen to the message queue for information about running jobs. |
---|
| 56 | |
---|
| 57 | The listener runs in a separate thread, allowing the listen |
---|
| 58 | call to return immediately. The callback is called each time |
---|
| 59 | there is a new message on the queue. If no callback is |
---|
| 60 | supplied, then a simple print is used. |
---|
| 61 | """ |
---|
| 62 | thread.start_new_thread(self._listener,(callback,)) |
---|
| 63 | |
---|
| 64 | |
---|
| 65 | |
---|
| 66 | class Fit(object): |
---|
| 67 | """ |
---|
| 68 | Coordinate the fit. |
---|
| 69 | """ |
---|
| 70 | update = on_fit_update |
---|
| 71 | complete = on_fit_complete |
---|
| 72 | def __init__(self, models = [], |
---|
| 73 | optimizer = None, |
---|
| 74 | service = None, |
---|
| 75 | update = None, |
---|
| 76 | complete = None): |
---|
| 77 | """ |
---|
| 78 | Set up the fit. |
---|
| 79 | |
---|
| 80 | models [] |
---|
| 81 | List of models which make up the assembly. |
---|
| 82 | optimizer |
---|
| 83 | Optimizer to use for the fit |
---|
| 84 | """ |
---|
| 85 | self.assembly = assembly.Assembly(models) |
---|
| 86 | self.optimizer = optimizer |
---|
| 87 | self.complete = complete |
---|
| 88 | self.update = update |
---|
| 89 | self.isrunning = False |
---|
| 90 | self._stopping = False |
---|
| 91 | |
---|
| 92 | def stop(self): |
---|
| 93 | """ |
---|
| 94 | Interrupt a running fit. |
---|
| 95 | """ |
---|
| 96 | self._stopping = True |
---|
| 97 | self.service.stop() |
---|
| 98 | |
---|
| 99 | def start(self): |
---|
| 100 | """ |
---|
| 101 | Start the fit. |
---|
| 102 | """ |
---|
| 103 | self.service.start() |
---|
| 104 | |
---|
| 105 | def _update(self, result): |
---|
| 106 | self.result = result |
---|
| 107 | if self.update: self.update(self,result) |
---|
| 108 | |
---|
| 109 | def _complete(self, result): |
---|
| 110 | self.result = result |
---|
| 111 | if self.complete: self.complete(self,result) |
---|
| 112 | |
---|
| 113 | def wait(self): |
---|
| 114 | """ |
---|
| 115 | Wait for a fit to complete. |
---|
| 116 | """ |
---|
| 117 | while self.isrunning: time.sleep(0.1) |
---|
| 118 | |
---|
| 119 | def fit(self): |
---|
| 120 | """ |
---|
| 121 | Start the fit and wait for the result. |
---|
| 122 | Returns the result. |
---|
| 123 | """ |
---|
| 124 | self.start() |
---|
| 125 | self.wait() |
---|
| 126 | return self.result |
---|