From 8ea84e6b70455881a7928aa7a3843321a117f977 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Wed, 23 Oct 2024 12:39:25 +0530 Subject: [PATCH] Use a mutex for registry CLI txs in webapp deployment commands --- .../webapp/publish_deployment_auction.py | 2 +- .../deploy/webapp/registry_mutex.py | 27 ++++++ stack_orchestrator/deploy/webapp/util.py | 83 ++++++++----------- 3 files changed, 62 insertions(+), 50 deletions(-) create mode 100644 stack_orchestrator/deploy/webapp/registry_mutex.py diff --git a/stack_orchestrator/deploy/webapp/publish_deployment_auction.py b/stack_orchestrator/deploy/webapp/publish_deployment_auction.py index 2a05ad17..bdc12eac 100644 --- a/stack_orchestrator/deploy/webapp/publish_deployment_auction.py +++ b/stack_orchestrator/deploy/webapp/publish_deployment_auction.py @@ -102,7 +102,7 @@ def command( "max_price": max_price, "num_providers": num_providers, } - auction_id = laconic.create_auction(provider_auction_params) + auction_id = laconic.create_deployment_auction(provider_auction_params) print("Deployment auction created:", auction_id) if not auction_id: diff --git a/stack_orchestrator/deploy/webapp/registry_mutex.py b/stack_orchestrator/deploy/webapp/registry_mutex.py new file mode 100644 index 00000000..82efdcf3 --- /dev/null +++ b/stack_orchestrator/deploy/webapp/registry_mutex.py @@ -0,0 +1,27 @@ +import fcntl +from functools import wraps + +# Define the file path for the lock +LOCK_FILE_PATH = "/tmp/registry_mutex_lock_file" + + +def registry_mutex(): + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + with open(LOCK_FILE_PATH, 'w') as lock_file: + try: + # Try to acquire the lock + fcntl.flock(lock_file, fcntl.LOCK_EX) + + # Call the actual function + result = func(*args, **kwargs) + finally: + # Always release the lock + fcntl.flock(lock_file, fcntl.LOCK_UN) + + return result + + return wrapper + + return decorator diff --git a/stack_orchestrator/deploy/webapp/util.py b/stack_orchestrator/deploy/webapp/util.py index 7b8914c0..5f63687c 100644 --- a/stack_orchestrator/deploy/webapp/util.py +++ b/stack_orchestrator/deploy/webapp/util.py @@ -26,6 +26,8 @@ import yaml from enum import Enum +from stack_orchestrator.deploy.webapp.registry_mutex import registry_mutex + class AuctionStatus(str, Enum): COMMIT = "commit" @@ -391,6 +393,7 @@ class LaconicRegistryClient: criteria["type"] = "ApplicationDeploymentAuction" return self.list_records(criteria, all) + @registry_mutex() def publish(self, record, names=None): if names is None: names = [] @@ -421,6 +424,7 @@ class LaconicRegistryClient: finally: logged_cmd(self.log_file, "rm", "-rf", tmpdir) + @registry_mutex() def set_name(self, name, record_id): logged_cmd( self.log_file, @@ -434,6 +438,7 @@ class LaconicRegistryClient: record_id, ) + @registry_mutex() def delete_name(self, name): logged_cmd( self.log_file, @@ -446,6 +451,7 @@ class LaconicRegistryClient: name, ) + @registry_mutex() def send_tokens(self, address, amount, type="alnt"): args = [ "laconic", @@ -464,58 +470,36 @@ class LaconicRegistryClient: return AttrDict(json.loads(logged_cmd(self.log_file, *args))) - def create_auction(self, auction): - if auction["kind"] == AUCTION_KIND_PROVIDER: - args = [ - "laconic", - "-c", - self.config_file, - "registry", - "auction", - "create", - "--kind", - auction["kind"], - "--commits-duration", - str(auction["commits_duration"]), - "--reveals-duration", - str(auction["reveals_duration"]), - "--denom", - auction["denom"], - "--commit-fee", - str(auction["commit_fee"]), - "--reveal-fee", - str(auction["reveal_fee"]), - "--max-price", - str(auction["max_price"]), - "--num-providers", - str(auction["num_providers"]) - ] - else: - args = [ - "laconic", - "-c", - self.config_file, - "registry", - "auction", - "create", - "--kind", - auction["kind"], - "--commits-duration", - str(auction["commits_duration"]), - "--reveals-duration", - str(auction["reveals_duration"]), - "--denom", - auction["denom"], - "--commit-fee", - str(auction["commit_fee"]), - "--reveal-fee", - str(auction["reveal_fee"]), - "--minimum-bid", - str(auction["minimum_bid"]) - ] + @registry_mutex() + def create_deployment_auction(self, auction): + args = [ + "laconic", + "-c", + self.config_file, + "registry", + "auction", + "create", + "--kind", + auction["kind"], + "--commits-duration", + str(auction["commits_duration"]), + "--reveals-duration", + str(auction["reveals_duration"]), + "--denom", + auction["denom"], + "--commit-fee", + str(auction["commit_fee"]), + "--reveal-fee", + str(auction["reveal_fee"]), + "--max-price", + str(auction["max_price"]), + "--num-providers", + str(auction["num_providers"]) + ] return json.loads(logged_cmd(self.log_file, *args))["auctionId"] + @registry_mutex() def commit_bid(self, auction_id, amount, type="alnt"): args = [ "laconic", @@ -532,6 +516,7 @@ class LaconicRegistryClient: return json.loads(logged_cmd(self.log_file, *args))["reveal_file"] + @registry_mutex() def reveal_bid(self, auction_id, reveal_file_path): logged_cmd( self.log_file,