Skip to content

EXECUTABLE visible to other threads before processing complete #742

@foxwoody

Description

@foxwoody

@liampauling as discussed there is a timing issue with replace operations where order.executable() is clearing the update_data fields AFTER setting the order status to executable. This early setting allows other threads to leap in with another replace operation all of which finally results in an exception due to a missing new_price key.

Fix that appears to work is to clear the update_data BEFORE the status turns to executable

    def executable(self) -> None:
        self.update_data.clear()
        self._update_status(OrderStatus.EXECUTABLE)

Also suggest following change to leave setting of any status change as late as possible so all changes are complete before other threads can see a changed status. This would help avoid similar timing issues of other threads jumping the gun before logging and trade adjustments are complete. BTW not checked if trade looks at order status - if it does then needs working around since will see status prior to this transition.

    def _update_status(self, status: OrderStatus) -> None:
        self.status_log.append(status)
        self.complete = self._is_complete()
        if logger.isEnabledFor(logging.INFO):
            logger.info("Order status update: %s" % self.status.value, extra=self.info)
        if self.complete and self.trade.complete and status != OrderStatus.VIOLATION:
            self.trade.complete_trade()
	    self.status = status

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions