Skip to content

Commit

Permalink
Made the Application into a component and moved subcomponent startup …
Browse files Browse the repository at this point in the history
…into Application.start()
  • Loading branch information
agronholm committed Sep 9, 2015
1 parent f08381c commit 013ccbc
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 27 deletions.
30 changes: 15 additions & 15 deletions asphalt/core/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
__all__ = 'Application',


class Application:
class Application(Component):
"""
This class orchestrates the configuration and setup of the chosen Asphalt components.
Expand Down Expand Up @@ -76,10 +76,11 @@ def add_component(self, component_alias: str, component_class: type=None, **comp
self.components.append(component)

def start(self, ctx: Context):
"""
This method can be overridden to provide additional resources to the components.
It can be a coroutine.
"""
# Start all the components and return a Future which completes when all the components
# have started
tasks = [retval for retval in (component.start(ctx) for component in self.components)
if retval is not None]
return asyncio.gather(*tasks)

def run(self):
# Configure the logging system
Expand All @@ -88,25 +89,24 @@ def run(self):
elif self.logging_config:
logging.basicConfig(level=logging.INFO)

# This is necessary to make @asynchronous work
util.event_loop = asyncio.get_event_loop()
util.event_loop_thread_id = threading.get_ident()

# Assign a new default executor with the given max worker thread limit
event_loop = asyncio.get_event_loop()
event_loop.set_default_executor(ThreadPoolExecutor(self.max_threads))

# This is necessary to make @asynchronous work
util.event_loop = event_loop
util.event_loop_thread_id = threading.get_ident()

# Create the application context
context = self.create_context()

try:
# Call the start() method of the application and all the components and run the loop
# until all the returned awaitables have finished
# Call the application's start() method.
# If it returns an awaitable, run the event loop until it's done.
self.logger.info('Starting application')
coroutines = [self.start(context)]
coroutines.extend(component.start(context) for component in self.components)
coroutines = [coro for coro in coroutines if coro is not None]
event_loop.run_until_complete(asyncio.gather(*coroutines))
retval = self.start(context)
if retval is not None:
event_loop.run_until_complete(retval)

# Run all the application context's start callbacks
event_loop.run_until_complete(context.dispatch('started'))
Expand Down
10 changes: 4 additions & 6 deletions asphalt/core/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,12 @@ def quickstart_application():
class {app_subclass}({app_cls.__name__}):
def __init__(self, **config):
super().__init__(**config)
# ADD COMPONENTS HERE
@coroutine
def start(ctx: Context):
# ADD ADDITIONAL RESOURCES HERE (if needed)
pass
# Add components and resources here as needed
self.add_component('foo')
yield from super().start(ctx)
# The components have started now
""".format(app_cls=Application, context_cls=Context, app_subclass=app_subclass))

with (project / 'config.yml').open('w') as f:
Expand Down
1 change: 1 addition & 0 deletions tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def started_callback(ctx):
def finished_callback(ctx):
self.finish_callback_called = True

yield from super().start(ctx)
ctx.add_listener('started', started_callback)
ctx.add_listener('finished', finished_callback)
ctx.shutter.shutdown()
Expand Down
10 changes: 4 additions & 6 deletions tests/test_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,12 @@ def mock_input(text):
class ExampleProjectApplication(Application):
def __init__(self, **config):
super().__init__(**config)
# ADD COMPONENTS HERE
@coroutine
def start(ctx: Context):
# ADD ADDITIONAL RESOURCES HERE (if needed)
pass
# Add components and resources here as needed
self.add_component('foo')
yield from super().start(ctx)
# The components have started now
"""

with projectdir.join('config.yml').open() as f:
Expand Down

0 comments on commit 013ccbc

Please sign in to comment.