@andymitchhank/

wielding-threaded-async-magic

Python

Based on the article @ https://tryexceptpass.org/article/threaded-asynchronous-magic-and-how-to-wield-it/

fork
loading
Files
  • main.py
  • decorators.py

This Plugin Crashed!

Error: Error: must not create an existing file {"type":"CREATE_FILE","wid":"0.78051439919955","path":"main.py","file":{"path":"main.py","content":{"asEncoding":{"base64":"aW1wb3J0IGFzeW5jaW8KaW1wb3J0IHNpZ25hbApmcm9tIHRocmVhZGluZyBpbXBvcnQgVGhyZWFkCmltcG9ydCB0aW1lCgpmcm9tIGRlY29yYXRvcnMgaW1wb3J0IGxvZ2dlcgoKCkBsb2dnZXIKYXN5bmMgZGVmIGRvX3NvbWVfd29yayh4KToKCWF3YWl0IGFzeW5jaW8uc2xlZXAoeCkKCgpAbG9nZ2VyCmRlZiBtb3JlX3dvcmsoeCk6Cgl0aW1lLnNsZWVwKHgpCgoKQGxvZ2dlcgpkZWYgYmxvY2tfdGhlX21haW5fdGhyZWFkKCk6Cglsb29wID0gYXN5bmNpby5nZXRfZXZlbnRfbG9vcCgpCglsb29wLnJ1bl91bnRpbF9jb21wbGV0ZShkb19zb21lX3dvcmsoNSkpCgoJdGFza3MgPSBbCgkgICAgYXN5bmNpby5lbnN1cmVfZnV0dXJlKGRvX3NvbWVfd29yaygyKSksCgkgICAgYXN5bmNpby5lbnN1cmVfZnV0dXJlKGRvX3NvbWVfd29yayg1KSkKCV0KCglsb29wLnJ1bl91bnRpbF9jb21wbGV0ZShhc3luY2lvLmdhdGhlcigqdGFza3MpKQoKCmRlZiBzdGFydF9sb29wKGxvb3ApOgoJYXN5bmNpby5zZXRfZXZlbnRfbG9vcChsb29wKQoJbG9vcC5ydW5fZm9yZXZlcigpCgoKQGxvZ2dlcgpkZWYgb25fYV9uZXdfdGhyZWFkKCk6CgluZXdfbG9vcCA9IGFzeW5jaW8ubmV3X2V2ZW50X2xvb3AoKQoJdCA9IFRocmVhZCh0YXJnZXQ9c3RhcnRfbG9vcCwgYXJncz0obmV3X2xvb3AsICkpCgl0LnN0YXJ0KCkKCgluZXdfbG9vcC5jYWxsX3Nvb25fdGhyZWFkc2FmZShtb3JlX3dvcmssIDIwKQoJYXN5bmNpby5ydW5fY29yb3V0aW5lX3RocmVhZHNhZmUoZG9fc29tZV93b3JrKDUpLCBuZXdfbG9vcCkKCWxhc3RfZnV0dXJlID0gYXN5bmNpby5ydW5fY29yb3V0aW5lX3RocmVhZHNhZmUoZG9fc29tZV93b3JrKDEwKSwgbmV3X2xvb3ApCgoJIyBTaW5jZSB3ZSBrbm93IHdoaWNoIGNvcm91dGluZSB3aWxsIGZpbmlzaCBsYXN0LAoJIyB3ZSBjYW4gc3RvcCB0aGUgbG9vcCB3aGVuIGl0J3MgZG9uZQoJbGFzdF9mdXR1cmUuYWRkX2RvbmVfY2FsbGJhY2sobGFtYmRhIGY6IG5ld19sb29wLnN0b3AoKSkKCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgoJYmxvY2tfdGhlX21haW5fdGhyZWFkKCkKCW9uX2FfbmV3X3RocmVhZCgpCg=="},"asBuffer":null},"loaded":true}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import asyncio
import signal
from threading import Thread
import time

from decorators import logger


@logger
async def do_some_work(x):
	await asyncio.sleep(x)


@logger
def more_work(x):
	time.sleep(x)


@logger
def block_the_main_thread():
	loop = asyncio.get_event_loop()
	loop.run_until_complete(do_some_work(5))

	tasks = [
	    asyncio.ensure_future(do_some_work(2)),
	    asyncio.ensure_future(do_some_work(5))
	]

	loop.run_until_complete(asyncio.gather(*tasks))


def start_loop(loop):
	asyncio.set_event_loop(loop)
	loop.run_forever()


@logger
def on_a_new_thread():
	new_loop = asyncio.new_event_loop()
	t = Thread(target=start_loop, args=(new_loop, ))
	t.start()

	new_loop.call_soon_threadsafe(more_work, 20)
	asyncio.run_coroutine_threadsafe(do_some_work(5), new_loop)
	last_future = asyncio.run_coroutine_threadsafe(do_some_work(10), new_loop)

	# Since we know which coroutine will finish last,
	# we can stop the loop when it's done
	last_future.add_done_callback(lambda f: new_loop.stop())


if __name__ == '__main__':
	block_the_main_thread()
	on_a_new_thread()