def save_command(self, command: offchain.Command) -> None: """save command locks prior command by reference id, validate and save new command. in a production implementation, the lock should be database / distributed lock to ensure atomic process(read and write) command by the reference id. """ lock = self.lock(command.reference_id()) if not lock.acquire(blocking=False): msg = f"command(reference_id={command.reference_id()}) is locked" raise offchain.command_error(offchain.ErrorCode.conflict, msg) try: prior = self.saved_commands.get(command.reference_id()) if command == prior: return command.validate(prior) self.saved_commands[command.reference_id()] = command if command.is_inbound(): self._enqueue_follow_up_action(command) else: # outbound self.task_queue.append(lambda app: app._send_request(command)) finally: lock.release()
def _enqueue_follow_up_action(self, command: offchain.Command) -> None: if command.follow_up_action(): self.task_queue.append(lambda app: app._offchain_business_action(command.reference_id()))