introduce a helper for a restartable task
(there are going to be a few of these)
This commit is contained in:
parent
2d1bd0011d
commit
eb228ab7f3
|
@ -16,11 +16,43 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
|
|
||||||
|
def _done(fut):
|
||||||
|
try:
|
||||||
|
fut.result()
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def schedule_task(coro):
|
def schedule_task(coro):
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
loop.call_soon(asyncio.ensure_future, coro)
|
if asyncio.iscoroutine(coro):
|
||||||
|
task = asyncio.Task(coro)
|
||||||
|
else:
|
||||||
|
task = coro
|
||||||
|
task.add_done_callback(_done)
|
||||||
|
loop.call_soon(asyncio.ensure_future, task)
|
||||||
|
return task
|
||||||
|
|
||||||
|
|
||||||
async def run_in_thread(func, *args):
|
async def run_in_thread(func, *args):
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
return await loop.run_in_executor(None, func, *args)
|
return await loop.run_in_executor(None, func, *args)
|
||||||
|
|
||||||
|
|
||||||
|
class SingleInstanceTask:
|
||||||
|
|
||||||
|
def __init__(self, func):
|
||||||
|
self.func = func
|
||||||
|
self.task = None
|
||||||
|
|
||||||
|
async def start(self, *args, **kw):
|
||||||
|
if self.task is not None:
|
||||||
|
self.task.cancel()
|
||||||
|
try:
|
||||||
|
await self.task
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
pass
|
||||||
|
self.task = schedule_task(self.func(*args, **kw))
|
||||||
|
|
||||||
|
def start_sync(self, *args, **kw):
|
||||||
|
return schedule_task(self.start(*args, **kw))
|
||||||
|
|
|
@ -34,7 +34,7 @@ from subiquitycore.utils import (
|
||||||
from subiquitycore.file_util import write_file
|
from subiquitycore.file_util import write_file
|
||||||
from subiquitycore import netplan
|
from subiquitycore import netplan
|
||||||
|
|
||||||
from subiquity.async_helpers import schedule_task
|
from subiquity.async_helpers import SingleInstanceTask
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger("subiquitycore.controller.network")
|
log = logging.getLogger("subiquitycore.controller.network")
|
||||||
|
@ -129,7 +129,7 @@ class NetworkController(BaseController):
|
||||||
self.model = app.base_model.network
|
self.model = app.base_model.network
|
||||||
self.view = None
|
self.view = None
|
||||||
self.view_shown = False
|
self.view_shown = False
|
||||||
self.apply_config_task = None
|
self.apply_config_task = SingleInstanceTask(self._apply_config)
|
||||||
if self.opts.dry_run:
|
if self.opts.dry_run:
|
||||||
self.root = os.path.abspath(".subiquity")
|
self.root = os.path.abspath(".subiquity")
|
||||||
netplan_path = self.netplan_path
|
netplan_path = self.netplan_path
|
||||||
|
@ -282,7 +282,7 @@ class NetworkController(BaseController):
|
||||||
self.update_initial_configs()
|
self.update_initial_configs()
|
||||||
self.view = NetworkView(self.model, self)
|
self.view = NetworkView(self.model, self)
|
||||||
if not self.view_shown:
|
if not self.view_shown:
|
||||||
self.apply_config_start()
|
self.apply_config(silent=True)
|
||||||
self.view_shown = True
|
self.view_shown = True
|
||||||
self.network_event_receiver.view = self.view
|
self.network_event_receiver.view = self.view
|
||||||
self.ui.set_body(self.view)
|
self.ui.set_body(self.view)
|
||||||
|
@ -298,18 +298,8 @@ class NetworkController(BaseController):
|
||||||
netplan_config_file_name = '00-snapd-config.yaml'
|
netplan_config_file_name = '00-snapd-config.yaml'
|
||||||
return os.path.join(self.root, 'etc/netplan', netplan_config_file_name)
|
return os.path.join(self.root, 'etc/netplan', netplan_config_file_name)
|
||||||
|
|
||||||
def apply_config_start(self, silent=False):
|
def apply_config(self, silent=False):
|
||||||
schedule_task(self.apply_config(silent))
|
self.apply_config_task.start_sync(silent)
|
||||||
|
|
||||||
async def apply_config(self, silent):
|
|
||||||
if self.apply_config_task is not None:
|
|
||||||
self.apply_config_task.cancel()
|
|
||||||
try:
|
|
||||||
await self.apply_config_task
|
|
||||||
except asyncio.CancelledError:
|
|
||||||
pass
|
|
||||||
self.apply_config_task = asyncio.ensure_future(
|
|
||||||
self._apply_config(silent))
|
|
||||||
|
|
||||||
async def _down_devs(self, devs):
|
async def _down_devs(self, devs):
|
||||||
for dev in devs:
|
for dev in devs:
|
||||||
|
|
|
@ -274,6 +274,7 @@ class AsyncioEventLoop(urwid.AsyncioEventLoop):
|
||||||
def _exception_handler(self, loop, context):
|
def _exception_handler(self, loop, context):
|
||||||
exc = context.get('exception')
|
exc = context.get('exception')
|
||||||
if exc:
|
if exc:
|
||||||
|
log.debug("_exception_handler %r", exc)
|
||||||
loop.stop()
|
loop.stop()
|
||||||
if not isinstance(exc, urwid.ExitMainLoop):
|
if not isinstance(exc, urwid.ExitMainLoop):
|
||||||
# Store the exc_info so we can re-raise after the loop stops
|
# Store the exc_info so we can re-raise after the loop stops
|
||||||
|
|
|
@ -136,7 +136,7 @@ class NetworkView(BaseView):
|
||||||
self.del_link(device)
|
self.del_link(device)
|
||||||
for dev in touched_devs:
|
for dev in touched_devs:
|
||||||
self.update_link(dev)
|
self.update_link(dev)
|
||||||
self.controller.apply_config_start()
|
self.controller.apply_config()
|
||||||
|
|
||||||
def _action(self, sender, action, device):
|
def _action(self, sender, action, device):
|
||||||
action, meth = action
|
action, meth = action
|
||||||
|
|
|
@ -250,7 +250,7 @@ class EditNetworkStretchy(Stretchy):
|
||||||
self.device.config['dhcp{v}'.format(v=self.ip_version)] = True
|
self.device.config['dhcp{v}'.format(v=self.ip_version)] = True
|
||||||
else:
|
else:
|
||||||
log.debug("EditNetworkStretchy %s, disabled", self.ip_version)
|
log.debug("EditNetworkStretchy %s, disabled", self.ip_version)
|
||||||
self.parent.controller.apply_config_start()
|
self.parent.controller.apply_config()
|
||||||
self.parent.update_link(self.device)
|
self.parent.update_link(self.device)
|
||||||
self.parent.remove_overlay()
|
self.parent.remove_overlay()
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ class AddVlanStretchy(Stretchy):
|
||||||
dev = self.parent.controller.add_vlan(
|
dev = self.parent.controller.add_vlan(
|
||||||
self.device, self.form.vlan.value)
|
self.device, self.form.vlan.value)
|
||||||
self.parent.new_link(dev)
|
self.parent.new_link(dev)
|
||||||
self.parent.controller.apply_config_start()
|
self.parent.controller.apply_config()
|
||||||
|
|
||||||
def cancel(self, sender=None):
|
def cancel(self, sender=None):
|
||||||
self.parent.remove_overlay()
|
self.parent.remove_overlay()
|
||||||
|
@ -487,7 +487,7 @@ class BondStretchy(Stretchy):
|
||||||
for dev in touched_devices:
|
for dev in touched_devices:
|
||||||
self.parent.update_link(dev)
|
self.parent.update_link(dev)
|
||||||
self.parent.remove_overlay()
|
self.parent.remove_overlay()
|
||||||
self.parent.controller.apply_config_start()
|
self.parent.controller.apply_config()
|
||||||
|
|
||||||
def cancel(self, sender=None):
|
def cancel(self, sender=None):
|
||||||
self.parent.remove_overlay()
|
self.parent.remove_overlay()
|
||||||
|
|
Loading…
Reference in New Issue