6 changed files with 136 additions and 84 deletions
@ -0,0 +1,67 @@ |
|||
# Copyright (c) 2018, Neil Booth |
|||
# |
|||
# All rights reserved. |
|||
# |
|||
# The MIT License (MIT) |
|||
# |
|||
# Permission is hereby granted, free of charge, to any person obtaining |
|||
# a copy of this software and associated documentation files (the |
|||
# "Software"), to deal in the Software without restriction, including |
|||
# without limitation the rights to use, copy, modify, merge, publish, |
|||
# distribute, sublicense, and/or sell copies of the Software, and to |
|||
# permit persons to whom the Software is furnished to do so, subject to |
|||
# the following conditions: |
|||
# |
|||
# The above copyright notice and this permission notice shall be |
|||
# included in all copies or substantial portions of the Software. |
|||
# |
|||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
|||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
|||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|||
# and warranty status of this software. |
|||
|
|||
'''Concurrency via tasks and threads.''' |
|||
|
|||
from concurrent.futures import ThreadPoolExecutor |
|||
|
|||
from aiorpcx import TaskSet |
|||
|
|||
import electrumx.lib.util as util |
|||
|
|||
|
|||
class Tasks(object): |
|||
# Functionality here will be incorporated into aiorpcX's TaskSet |
|||
# after experience is gained. |
|||
|
|||
def __init__(self, *, loop=None): |
|||
self.tasks = TaskSet(loop=loop) |
|||
self.logger = util.class_logger(__name__, self.__class__.__name__) |
|||
# FIXME: is the executor still needed? |
|||
self.executor = ThreadPoolExecutor() |
|||
self.tasks.loop.set_default_executor(self.executor) |
|||
# Pass through until integrated |
|||
self.loop = self.tasks.loop |
|||
self.cancel_all = self.tasks.cancel_all |
|||
self.wait = self.tasks.wait |
|||
|
|||
async def run_in_thread(self, func, *args): |
|||
'''Run a function in a separate thread, and await its completion.''' |
|||
return await self.loop.run_in_executor(None, func, *args) |
|||
|
|||
def create_task(self, coro, callback=None): |
|||
'''Schedule the coro to be run.''' |
|||
task = self.tasks.create_task(coro) |
|||
task.add_done_callback(callback or self._check_task_exception) |
|||
return task |
|||
|
|||
def _check_task_exception(self, task): |
|||
'''Check a task for exceptions.''' |
|||
try: |
|||
if not task.cancelled(): |
|||
task.result() |
|||
except Exception as e: |
|||
self.logger.exception(f'uncaught task exception: {e}') |
Loading…
Reference in new issue