@@ -45,8 +45,13 @@ engine = Engine()
45
45
def add (a , b ):
46
46
return a + b
47
47
48
+ async def add_async (a , b ):
49
+ # async function can also be used as the job function
50
+ await asyncio.sleep(1.0 )
51
+ return a + b
52
+
48
53
async def main ():
49
- job1 = ProcessJob(add , args = (1 , 2 ))
54
+ job1 = ProcessJob(add_async , args = (1 , 2 ))
50
55
job2 = ProcessJob(add, args = (job1.future, 4 ))
51
56
await engine.submit_async(job1, job2)
52
57
await engine.join()
@@ -96,73 +101,6 @@ They are executed by different backends and suitable for different scenarios.
96
101
| ` ProcessJob ` | ` executor.engine.backend.process ` | CPU-bound tasks |
97
102
| ` DaskJob ` | ` executor.engine.backend.dask ` | Distributed tasks |
98
103
99
- ### Extend job types
100
-
101
- There are two extend job types:
102
- [ ` SubprocessJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.SubprocessJob )
103
- and
104
- [ ` WebappJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.WebappJob )
105
- . They are used to execute shell commands and launch web applications.
106
- The extend job types can based on the job types above(` LocalJob ` , ` ThreadJob ` , ` ProcessJob ` , ` DaskJob ` ).
107
-
108
- #### SubprocessJob
109
-
110
- [ ` SubprocessJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.SubprocessJob )
111
- is a job type for executing shell commands.
112
- ` SubprocessJob ` accept a shell command as its argument. It will execute the command in a subprocess:
113
-
114
- ``` python
115
- from executor.engine import Engine
116
- from executor.engine.job.extend import SubprocessJob
117
-
118
- job = SubprocessJob(
119
- " python -c 'print(1 + 2)'" ,
120
- )
121
-
122
- with Engine() as engine:
123
- engine.submit(job)
124
- engine.wait_job(job)
125
- ```
126
-
127
-
128
- #### WebappJob
129
-
130
- [ ` WebappJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.WebappJob )
131
- is a job type for launching a web application.
132
- It can accept a function with ` ip ` and ` port ` as arguments:
133
-
134
- ``` python
135
- from executor.engine import Engine
136
- from executor.engine.job.extend import WebappJob
137
- from http.server import HTTPServer, SimpleHTTPRequestHandler
138
-
139
- def run_simple_httpd (ip : str , port : int ):
140
- server_addr = (ip, port)
141
- httpd = HTTPServer(server_addr, SimpleHTTPRequestHandler)
142
- httpd.serve_forever()
143
-
144
- with Engine() as engine:
145
- job = WebappJob(run_simple_httpd, ip = " 127.0.0.1" , port = 8000 )
146
- engine.submit(job)
147
- print (" Open your browser and visit http://127.0.0.1:8000" )
148
- engine.wait()
149
- ```
150
-
151
- ` WebappJob ` can also accept a command template as its argument:
152
-
153
- ``` python
154
- from executor.engine import Engine
155
- from executor.engine.job.extend import WebappJob
156
-
157
- with Engine() as engine:
158
- job = WebappJob(
159
- " python -m http.server -b {ip} {port} " ,
160
- ip = " 127.0.0.1" , port = 8000 )
161
- engine.submit(job)
162
- print (" Open your browser and visit http://127.0.0.1:8000" )
163
- engine.wait()
164
- ```
165
-
166
104
### Conditional job execution
167
105
168
106
After another job:
@@ -284,6 +222,42 @@ with Engine() as engine:
284
222
engine.wait()
285
223
```
286
224
225
+ ##### Syntactic sugar for condition combination
226
+
227
+ You can use ` & ` and ` | ` to combine conditions:
228
+
229
+ ``` python
230
+ from executor.engine import Engine, ThreadJob
231
+ from executor.engine.job.condition import AfterAnother
232
+ import time
233
+
234
+ s = set ()
235
+
236
+ def sleep_and_add_1 (t : int ):
237
+ time.sleep(t)
238
+ s.add(t)
239
+
240
+ def has_two_elements ():
241
+ print (s)
242
+ assert len (s) == 2
243
+
244
+ with Engine() as engine:
245
+ job1 = ThreadJob(sleep_and_add_1, args = (1 ,))
246
+ job2 = ThreadJob(sleep_and_add_1, args = (2 ,))
247
+ job3 = ThreadJob(sleep_and_add_1, args = (3 ,))
248
+ job4 = ThreadJob(
249
+ has_two_elements,
250
+ condition = (
251
+ (
252
+ AfterAnother(job_id = job1.id) &
253
+ AfterAnother(job_id = job2.id)
254
+ ) |
255
+ AfterAnother(job_id = job3.id)
256
+ )
257
+ )
258
+ engine.submit(job4, job3, job2, job1)
259
+ engine.wait()
260
+ ```
287
261
288
262
#### Custom condition
289
263
@@ -319,6 +293,123 @@ with Engine() as engine:
319
293
engine.wait()
320
294
```
321
295
296
+ ### Extend job types
297
+
298
+ There are 4 extend job types:
299
+ [ ` SubprocessJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.SubprocessJob ) ,
300
+ [ ` WebappJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.WebappJob )
301
+ [ ` SentinelJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.SentinelJob )
302
+ [ ` CronJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.CronJob )
303
+
304
+ They are used to execute shell commands, launch web applications
305
+ and schedule jobs based on time. The extend job types can based on the job types above(` LocalJob ` , ` ThreadJob ` , ` ProcessJob ` , ` DaskJob ` ).
306
+
307
+ #### SubprocessJob
308
+
309
+ [ ` SubprocessJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.SubprocessJob )
310
+ is a job type for executing shell commands.
311
+ ` SubprocessJob ` accept a shell command as its argument. It will execute the command in a subprocess:
312
+
313
+ ``` python
314
+ from executor.engine import Engine
315
+ from executor.engine.job.extend import SubprocessJob
316
+
317
+ job = SubprocessJob(
318
+ " python -c 'print(1 + 2)'" ,
319
+ )
320
+
321
+ with Engine() as engine:
322
+ engine.submit(job)
323
+ engine.wait_job(job)
324
+ ```
325
+
326
+
327
+ #### WebappJob
328
+
329
+ [ ` WebappJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.WebappJob )
330
+ is a job type for launching a web application.
331
+ It can accept a function with ` ip ` and ` port ` as arguments:
332
+
333
+ ``` python
334
+ from executor.engine import Engine
335
+ from executor.engine.job.extend import WebappJob
336
+ from http.server import HTTPServer, SimpleHTTPRequestHandler
337
+
338
+ def run_simple_httpd (ip : str , port : int ):
339
+ server_addr = (ip, port)
340
+ httpd = HTTPServer(server_addr, SimpleHTTPRequestHandler)
341
+ httpd.serve_forever()
342
+
343
+ with Engine() as engine:
344
+ job = WebappJob(run_simple_httpd, ip = " 127.0.0.1" , port = 8000 )
345
+ engine.submit(job)
346
+ print (" Open your browser and visit http://127.0.0.1:8000" )
347
+ engine.wait()
348
+ ```
349
+
350
+ ` WebappJob ` can also accept a command template as its argument:
351
+
352
+ ``` python
353
+ from executor.engine import Engine
354
+ from executor.engine.job.extend import WebappJob
355
+
356
+ with Engine() as engine:
357
+ job = WebappJob(
358
+ " python -m http.server -b {ip} {port} " ,
359
+ ip = " 127.0.0.1" , port = 8000 )
360
+ engine.submit(job)
361
+ print (" Open your browser and visit http://127.0.0.1:8000" )
362
+ engine.wait()
363
+ ```
364
+
365
+ #### CronJob
366
+
367
+ [ ` CronJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.CronJob )
368
+ is a job type for scheduling jobs periodically.
369
+ It should be used with different ` TimeCondition ` for different scheduling strategies. For example:
370
+
371
+ ``` python
372
+ from executor.engine import Engine
373
+ from executor.engine.job.extend.cron import (
374
+ CronJob, every,
375
+ hourly, daily, weekly,
376
+ after_clock, between_clock,
377
+ after_weekday,
378
+ )
379
+
380
+
381
+ def do_something ():
382
+ print (" hello" )
383
+
384
+
385
+ with Engine() as engine:
386
+ # will run the function every 10 seconds
387
+ job1 = CronJob(do_something, every(" 10s" ))
388
+ # will run the function every minute
389
+ job2 = CronJob(do_something, every(" 1m" ))
390
+ # will run the function every hour
391
+ job3 = CronJob(do_something, hourly)
392
+ # will run the function every day at 12:00
393
+ job4 = CronJob(do_something, daily & after_clock(" 12:00" ))
394
+ # will run the function every week on Monday at 12:00
395
+ job5 = CronJob(
396
+ do_something,
397
+ weekly & after_weekday(" Monday" ) & after_clock(" 12:00" ))
398
+ # will run the function every 5min at the night
399
+ job6 = CronJob(do_something, every(" 5m" ) & between_clock(" 18:00" , " 24:00" ))
400
+ engine.submit(job1, job2, job3, job4, job5, job6)
401
+ engine.wait()
402
+ ```
403
+
404
+ See [ CronJob] ( api-reference/extend_job.md#executor.engine.job.extend.CronJob ) for more details.
405
+
406
+ !!! info
407
+ ` CronJob ` is a special kind of
408
+ [ ` SentinelJob ` ] ( api-reference/extend_job.md#executor.engine.job.extend.SentinelJob ) ,
409
+ ` SentinelJob ` is a more general kind of job, it will be
410
+ submit other jobs when the condition is satisfied.
411
+
412
+
322
413
### Generator support
323
414
324
415
` executor.engine ` supports generator job, which is a special job that returns a generator.
0 commit comments