async def draw(messages_queue, sending_queue, status_updates_queue): root = tk.Tk() root.title('Чат Майнкрафтера') root_frame = tk.Frame() root_frame.pack(fill="both", expand=True) status_labels = create_status_panel(root_frame) input_frame = tk.Frame(root_frame) input_frame.pack(side="bottom", fill=tk.X) input_field = tk.Entry(input_frame) input_field.pack(side="left", fill=tk.X, expand=True) input_field.bind("<Return>", lambda event: process_new_message(input_field, sending_queue)) send_button = tk.Button(input_frame) send_button["text"] = "Отправить" send_button["command"] = lambda: process_new_message(input_field, sending_queue) send_button.pack(side="left") conversation_panel = ScrolledText(root_frame, wrap='none') conversation_panel.pack(side="top", fill="both", expand=True) async with create_handy_nursery() as nursery: nursery.start_soon(update_tk(root_frame)) nursery.start_soon(update_conversation_history(conversation_panel, messages_queue)) nursery.start_soon(update_status_panel(status_labels, status_updates_queue))
async def test_handy_nursery_single_exception(): async def f(): raise ValueError with pytest.raises(ValueError): async with helpers.create_handy_nursery() as nursery: nursery.start_soon(f())
async def test_handy_nursery_multiple_exception(): async def f(): raise ValueError async def g(): raise KeyError with pytest.raises(aionursery.MultiError): async with helpers.create_handy_nursery() as nursery: nursery.start_soon(f()) nursery.start_soon(g())
async def run_app( reader_address: str, writer_address: str, access_token: str, history_path: str, greetings: List[str], ) -> None: """entry point coroutine, just runs all the things""" # I don't know why here should be type annotations, but mypy said so messages_queue: asyncio.Queue = asyncio.Queue() sending_queue: asyncio.Queue = asyncio.Queue() status_updates_queue: asyncio.Queue = asyncio.Queue() history_queue: asyncio.Queue = asyncio.Queue() watchdog_queue: asyncio.Queue = asyncio.Queue() async with create_handy_nursery() as nursery: # it's messages queue consumer, so run it first in background nursery.start_soon( gui.draw( messages_queue=messages_queue, sending_queue=sending_queue, status_updates_queue=status_updates_queue, )) # send greetings and history into messages queue await send_greetings(greetings, messages_queue) await history.restore(history_path, messages_queue) nursery.start_soon( history.save( path=history_path, history_queue=history_queue, )) nursery.start_soon( handle_connection( reader_address=reader_address, writer_address=writer_address, access_token=access_token, messages_queue=messages_queue, input_queue=sending_queue, history_queue=history_queue, watchdog_queue=watchdog_queue, state_queue=status_updates_queue, ))
async def handle_connection( reader_address: str, writer_address: str, access_token: str, messages_queue: asyncio.Queue, input_queue: asyncio.Queue, history_queue: asyncio.Queue, watchdog_queue: asyncio.Queue, state_queue: asyncio.Queue, ) -> None: """just starts coroutines and handle ConnectionExceptions""" try: async with create_handy_nursery() as nursery: nursery.start_soon( watch_for_connection( events_queue=watchdog_queue, timeout=2, )) nursery.start_soon( clients.read_messages( address=reader_address, state_queue=state_queue, message_queues=[messages_queue, history_queue], watchdog_queue=watchdog_queue, msg_filter=is_bot, # msg_filter=None, )) nursery.start_soon( clients.send_messages( address=writer_address, access_token=access_token, state_queue=state_queue, input_queue=input_queue, watchdog_queue=watchdog_queue, )) except socket.gaierror: raise ConnectionError except aionursery.MultiError as ex: if any(isinstance(e, socket.gaierror) for e in ex.exceptions): raise ConnectionError elif any(isinstance(e, ConnectionError) for e in ex.exceptions): raise ConnectionError else: raise