Skip to content

Commit c71b5af

Browse files
committed
update transaction middleware
1 parent 5bade23 commit c71b5af

File tree

7 files changed

+76
-41
lines changed

7 files changed

+76
-41
lines changed

.github/workflows/pytest.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ jobs:
3535
uses: actions/setup-python@v3
3636
with:
3737
python-version: "3.10"
38-
- uses: Gr1N/setup-poetry@v7
38+
- name: Install Poetry
39+
run: |
40+
pip install poetry
41+
poetry self update
3942
- name: Install dependencies
4043
run: poetry install
4144
- name: Run all tests

poetry.lock

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ bcrypt = "^4.0.1"
3333
poethepoet = "^0.10.0"
3434
pytest-cov = "^2.12.1"
3535
mypy = "^0.910"
36+
vulture = "^2.7"
3637

3738
[build-system]
3839
requires = ["poetry-core>=1.0.0"]

src/api/tests/test_bidding.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def setup_app_for_bidding_tests(app, listing_id, seller_id, bidder_id):
3737
)
3838
)
3939
app.execute_command(PublishListingDraftCommand(listing_id=listing_id))
40-
logger.info("setup complete")
40+
logger.info("test setup complete")
4141

4242

4343
@pytest.mark.integration

src/config/container.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,25 +108,36 @@ def on_enter_transaction_context(ctx):
108108
db_session=session, correlation_id=correlation_id, logger=logger
109109
)
110110
ctx.dependency_provider = IocProvider(transaction_container)
111-
logger.info(f"session={id(session)} transaction started")
111+
logger.info(f"{id(session)} transaction started")
112112

113113
@application.on_exit_transaction_context
114114
def on_exit_transaction_context(ctx, exc_type, exc_val, exc_tb):
115115
session = ctx.dependency_provider.get_dependency("db_session")
116116
if exc_type:
117117
session.rollback()
118-
logger.info(f"session={id(session)} rollback due to {exc_type}")
118+
logger.info(f"{id(session)} rollback due to {exc_type}")
119119
else:
120120
session.commit()
121-
logger.info(f"session={id(session)} committed")
121+
logger.info(f"{id(session)} committed")
122122
session.close()
123-
logger.info(f"session={id(session)} transaction ended ")
123+
logger.info(f"{id(session)} transaction ended ")
124124

125125
@application.transaction_middleware
126-
def logging_middleware(ctx, next):
126+
def logging_middleware(ctx, next, command=None, query=None, event=None):
127+
if command:
128+
prefix = "Executing"
129+
task = command
130+
elif query:
131+
prefix = "Querying"
132+
task = query
133+
elif event:
134+
prefix = "Handling"
135+
task = event
136+
task = command or query or event
127137
session = ctx.dependency_provider.get_dependency("db_session")
138+
logger.info(f"{id(session)} {prefix} {task}")
128139
result = next()
129-
logger.info(f"Task {ctx.task} executed successfully")
140+
logger.info(f"{id(session)} {prefix} completed, result: {result}")
130141
return result
131142

132143
return application

src/seedwork/application/__init__.py

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ def __exit__(self, exc_type, exc_val, exc_tb):
109109
"""Should be used to commit/end a transaction"""
110110
self.app._on_exit_transaction_context(self, exc_type, exc_val, exc_tb)
111111

112+
def _wrap_with_middlewares(
113+
self, handler_func, command=None, query=None, event=None
114+
):
115+
p = handler_func
116+
for middleware in self.app._transaction_middlewares:
117+
p = partial(middleware, self, p, command, query, event)
118+
return p
119+
112120
def execute_query(self, query):
113121
assert (
114122
self.task is None
@@ -119,13 +127,9 @@ def execute_query(self, query):
119127
handler_kwargs = self.dependency_provider.get_handler_kwargs(
120128
handler_func, **self.overrides
121129
)
122-
123-
# prepare query handler
124-
p = partial(handler_func, query, **handler_kwargs)
125-
126-
for middleware in self.app._transaction_middlewares:
127-
p = partial(middleware, self, p)
128-
result = p()
130+
handler_func = partial(handler_func, query, **handler_kwargs)
131+
wrapped_handler = self._wrap_with_middlewares(handler_func, query=query)
132+
result = wrapped_handler()
129133
return result
130134

131135
def execute_command(self, command):
@@ -138,39 +142,24 @@ def execute_command(self, command):
138142
handler_kwargs = self.dependency_provider.get_handler_kwargs(
139143
handler_func, **self.overrides
140144
)
141-
142-
# prepare command handler
143-
p = partial(handler_func, command, **handler_kwargs)
144-
145-
# wrap command handler in middlewares
146-
handler_kwargs = self.dependency_provider.get_handler_kwargs(
147-
handler_func, **self.overrides
148-
)
149-
p = partial(handler_func, command, **handler_kwargs)
150-
for middleware in self.app._transaction_middlewares:
151-
p = partial(middleware, self, p)
145+
handler_func = partial(handler_func, command, **handler_kwargs)
146+
wrapped_handler = self._wrap_with_middlewares(handler_func, command=command)
152147

153148
# execute wrapped command handler
154-
command_result = p()
149+
command_result = wrapped_handler()
155150

156151
self.next_commands = []
157152
self.integration_events = []
158153
event_queue = command_result.events.copy()
159154
while len(event_queue) > 0:
160155
event = event_queue.pop(0)
161156
if isinstance(event, IntegrationEvent):
162-
self.integration_events.append(result)
157+
self._process_integration_event(event)
158+
163159
elif isinstance(event, DomainEvent):
164-
for event_handler in self.app.get_event_handlers(event):
165-
handler_kwargs = self.dependency_provider.get_handler_kwargs(
166-
event_handler, **self.overrides
167-
)
168-
logger.info(f"handling event {event} with {event_handler}")
169-
result = event_handler(event, **handler_kwargs)
170-
if isinstance(result, Command):
171-
self.next_commands.append(result)
172-
elif isinstance(result, EventResult):
173-
event_queue.extend(result.events)
160+
new_command, new_events = self._process_domain_event(event)
161+
self.next_commands.extend(new_command)
162+
event_queue.extend(new_events)
174163

175164
return CommandResult.success(payload=command_result.payload)
176165

@@ -181,6 +170,25 @@ def get_service(self, service_cls):
181170
def current_user(self):
182171
return self.dependency_provider.get_dependency("current_user")
183172

173+
def _process_integration_event(self, event):
174+
self.integration_events.append(event)
175+
176+
def _process_domain_event(self, event):
177+
new_commands = []
178+
new_events = []
179+
for handler_func in self.app.get_event_handlers(event):
180+
handler_kwargs = self.dependency_provider.get_handler_kwargs(
181+
handler_func, **self.overrides
182+
)
183+
event_handler = partial(handler_func, event, **handler_kwargs)
184+
wrapped_handler = self._wrap_with_middlewares(event_handler, event=event)
185+
result = wrapped_handler()
186+
if isinstance(result, Command):
187+
new_commands.append(result)
188+
elif isinstance(result, EventResult):
189+
new_events.extend(result.events)
190+
return new_commands, new_events
191+
184192

185193
class ApplicationModule:
186194
def __init__(self, name, version=1.0):

src/seedwork/tests/application/test_application.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,12 @@ def test_transaction_context_middleware():
124124
app = Application(trace=[])
125125

126126
@app.transaction_middleware
127-
def middleware1(ctx, next):
127+
def middleware1(ctx, next, command=None, query=None, event=None):
128128
ctx.dependency_provider["trace"].append("middleware1")
129129
return next()
130130

131131
@app.transaction_middleware
132-
def middleware1(ctx, next):
132+
def middleware1(ctx, next, command=None, query=None, event=None):
133133
ctx.dependency_provider["trace"].append("middleware2")
134134
return next()
135135

0 commit comments

Comments
 (0)