From b5050bf026a52cea7645ee5ecdf152f96100dcab Mon Sep 17 00:00:00 2001 From: azawlocki Date: Tue, 30 Mar 2021 13:45:09 +0200 Subject: [PATCH 1/2] Add 5s timeout for market operations --- yapapi/executor/__init__.py | 59 +++++++++++++++++++++++-------------- yapapi/rest/market.py | 4 +-- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/yapapi/executor/__init__.py b/yapapi/executor/__init__.py index 789cbb30e..7c1013222 100644 --- a/yapapi/executor/__init__.py +++ b/yapapi/executor/__init__.py @@ -368,6 +368,32 @@ async def accept_payment_for_agreement(agreement_id: str, *, partial: bool = Fal ) async def find_offers() -> None: + async def reject_proposal(proposal, reason): + try: + await proposal.reject(reason=reason) + emit(events.ProposalRejected(prop_id=proposal.id, reason=reason)) + return True + except Exception: + emit( + events.ProposalFailed( + prop_id=proposal.id, exc_info=sys.exc_info() # type: ignore + ) + ) + return False + + async def respond_to_proposal(proposal, builder): + try: + await proposal.respond(builder.properties, builder.constraints) + emit(events.ProposalResponded(prop_id=proposal.id)) + return True + except Exception: + emit( + events.ProposalFailed( + prop_id=proposal.id, exc_info=sys.exc_info() # type: ignore + ) + ) + return False + nonlocal offers_collected, proposals_confirmed try: subscription = await builder.subscribe(market_api) @@ -394,12 +420,10 @@ async def find_offers() -> None: score, ) except InvalidPropertiesError as err: - emit(events.ProposalRejected(prop_id=proposal.id, reason=str(err))) + await reject_proposal(proposal, "Malformed offer") continue if score < SCORE_NEUTRAL: - with contextlib.suppress(Exception): - await proposal.reject(reason="Score too low") - emit(events.ProposalRejected(prop_id=proposal.id, reason="Score too low")) + await reject_proposal(proposal, "Score too low") elif not proposal.is_draft: try: common_platforms = self._get_common_payment_platforms(proposal) @@ -409,31 +433,22 @@ async def find_offers() -> None: ) else: # reject proposal if there are no common payment platforms - with contextlib.suppress(Exception): - await proposal.reject(reason="No common payment platform") - emit( - events.ProposalRejected( - prop_id=proposal.id, reason="No common payment platforms" - ) - ) + await reject_proposal(proposal, "No common payment platform") + continue timeout = proposal.props.get(DEBIT_NOTE_ACCEPTANCE_TIMEOUT_PROP) if timeout: if timeout < DEBIT_NOTE_MIN_TIMEOUT: - with contextlib.suppress(Exception): - await proposal.reject(reason="Debit note timeout too low") - emit( - events.ProposalRejected( - prop_id=proposal.id, - reason="Debit note acceptance timeout too short", - ) - ) + await reject_proposal(proposal, "No common payment platform") + continue else: builder.properties[DEBIT_NOTE_ACCEPTANCE_TIMEOUT_PROP] = timeout - await proposal.respond(builder.properties, builder.constraints) - emit(events.ProposalResponded(prop_id=proposal.id)) + if await respond_to_proposal(proposal, builder): + emit(events.ProposalResponded(prop_id=proposal.id)) + else: + continue except CancelledError: raise - except Exception as ex: + except Exception: emit( events.ProposalFailed( prop_id=proposal.id, exc_info=sys.exc_info() # type: ignore diff --git a/yapapi/rest/market.py b/yapapi/rest/market.py index 8fbf65514..cb80be488 100644 --- a/yapapi/rest/market.py +++ b/yapapi/rest/market.py @@ -123,14 +123,14 @@ def is_draft(self) -> bool: async def reject(self, reason: str = "Rejected"): """Reject the Offer.""" await self._subscription._api.reject_proposal_offer( - self._subscription.id, self.id, request_body={"message": reason} + self._subscription.id, self.id, request_body={"message": reason}, _request_timeout=5 ) async def respond(self, props: dict, constraints: str) -> str: """Create an agreeement Proposal for a received Offer, based on our Demand.""" proposal = models.DemandOfferBase(properties=props, constraints=constraints) new_proposal = await self._subscription._api.counter_proposal_demand( - self._subscription.id, self.id, proposal + self._subscription.id, self.id, proposal, _request_timeout=5 ) return new_proposal From 9a0af0fe5fbe310f9734f538ce9615fa6b3be041 Mon Sep 17 00:00:00 2001 From: azawlocki Date: Wed, 31 Mar 2021 11:57:27 +0200 Subject: [PATCH 2/2] Simplify the logic in find_offers() slightly; fix rejection message --- yapapi/executor/__init__.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/yapapi/executor/__init__.py b/yapapi/executor/__init__.py index 7c1013222..81f21bc85 100644 --- a/yapapi/executor/__init__.py +++ b/yapapi/executor/__init__.py @@ -372,27 +372,23 @@ async def reject_proposal(proposal, reason): try: await proposal.reject(reason=reason) emit(events.ProposalRejected(prop_id=proposal.id, reason=reason)) - return True except Exception: emit( events.ProposalFailed( prop_id=proposal.id, exc_info=sys.exc_info() # type: ignore ) ) - return False async def respond_to_proposal(proposal, builder): try: await proposal.respond(builder.properties, builder.constraints) emit(events.ProposalResponded(prop_id=proposal.id)) - return True except Exception: emit( events.ProposalFailed( prop_id=proposal.id, exc_info=sys.exc_info() # type: ignore ) ) - return False nonlocal offers_collected, proposals_confirmed try: @@ -438,14 +434,13 @@ async def respond_to_proposal(proposal, builder): timeout = proposal.props.get(DEBIT_NOTE_ACCEPTANCE_TIMEOUT_PROP) if timeout: if timeout < DEBIT_NOTE_MIN_TIMEOUT: - await reject_proposal(proposal, "No common payment platform") + await reject_proposal( + proposal, "Debit note acceptance timeout too short" + ) continue else: builder.properties[DEBIT_NOTE_ACCEPTANCE_TIMEOUT_PROP] = timeout - if await respond_to_proposal(proposal, builder): - emit(events.ProposalResponded(prop_id=proposal.id)) - else: - continue + await respond_to_proposal(proposal, builder) except CancelledError: raise except Exception: