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 |
---|