123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- """
- This module represents the Marketplace.
- Computer Systems Architecture Course
- Assignment 1
- March 2020
- """
- from threading import Lock
- class Marketplace:
- """
- Class that represents the Marketplace. It's the central part of the implementation.
- The producers and consumers use its methods concurrently.
- """
- debug = False
- def __init__(self, queue_size_per_producer):
- """
- Constructor
- :type queue_size_per_producer: Int
- :param queue_size_per_producer: the maximum size of a queue associated with each producer
- """
- self.queue_size_per_producer = queue_size_per_producer
- self.producer_lock = Lock()
- self.consumer_lock = Lock()
- self.producers_list = []
- self.available_products = []
- self.consumers_cart = []
- def register_producer(self):
- """
- Returns an id for the producer that calls this.
- """
- self.producer_lock.acquire()
- producer_id = len(self.producers_list)
- self.producers_list.append([])
- self.producer_lock.release()
- if self.debug:
- print("[REG_PROD] NEW")
- print("[REG_PROD] Producer " + str(producer_id) + " has registered.")
- return producer_id
- def publish(self, producer_id, product):
- """
- Adds the product provided by the producer to the marketplace
- :type producer_id: String
- :param producer_id: producer id
- :type product: Product
- :param product: the Product that will be published in the Marketplace
- :returns True or False. If the caller receives False, it should wait and then try again.
- """
- p_id = int(producer_id)
- if p_id >= len(self.producers_list):
- return False
- producer_list = self.producers_list[p_id]
- if self.queue_size_per_producer <= len(producer_list):
- return False
- producer_list.append(product)
- self.available_products.append(product)
- if self.debug:
- print("[PUBLISH] NEW")
- print("[PUBLISH] Producer " + str(producer_id) + " inserted element: " + str(product))
- print("[PUBLISH] Producer list: " + str(producer_list))
- print("[PUBLISH] Available products now: " + str(self.available_products))
- return True
- def new_cart(self):
- """
- Creates a new cart for the consumer
- :returns an int representing the cart_id
- """
- self.consumer_lock.acquire()
- cart_id = len(self.consumers_cart)
- self.consumers_cart.append([])
- self.consumer_lock.release()
- if self.debug:
- print("[NEW_CART] NEW")
- print("[NEW_CART] Cart " + str(cart_id) + " created.")
- return cart_id
- def add_to_cart(self, cart_id, product):
- """
- Adds a product to the given cart. The method returns
- :type cart_id: Int
- :param cart_id: id cart
- :type product: Product
- :param product: the product to add to cart
- :returns True or False. If the caller receives False, it should wait and then try again
- """
- if cart_id >= len(self.consumers_cart) or product not in self.available_products:
- return False
- self.consumer_lock.acquire()
- if product in self.available_products:
- self.available_products.remove(product)
- self.consumer_lock.release()
- self.consumers_cart[cart_id].append(product)
- if self.debug:
- print("[ADD_TO_CART] NEW")
- print("[ADD_TO_CART] Cart " + str(cart_id) + " has new element: " + str(product))
- print("[ADD_TO_CART] Cart contents: " + str(self.consumers_cart[cart_id]))
- print("[ADD_TO_CART] Available products now: " + str(self.available_products))
- return True
- def remove_from_cart(self, cart_id, product):
- """
- Removes a product from cart.
- :type cart_id: Int
- :param cart_id: id cart
- :type product: Product
- :param product: the product to remove from cart
- """
- if cart_id >= len(self.consumers_cart):
- return False
- cart = self.consumers_cart[cart_id]
- if product not in cart:
- return False
- self.available_products.append(product)
- cart.remove(product)
- if self.debug:
- print("[REMOVE_FROM_CART] NEW")
- print("[REMOVE_FROM_CART] Cart " + str(cart_id) + " removed element: " + str(product))
- print("[REMOVE_FROM_CART] Cart contents: " + str(cart))
- print("[REMOVE_FROM_CART] Available products now: " + str(self.available_products))
- return False
- def place_order(self, cart_id):
- """
- Return a list with all the products in the cart.
- :type cart_id: Int
- :param cart_id: id cart
- """
- if cart_id >= len(self.consumers_cart):
- return None
- cart = self.consumers_cart[cart_id]
- for product in cart:
- found_producer = False
- self.producer_lock.acquire()
- for producer_list in self.producers_list:
- if not found_producer:
- for producer_product in producer_list:
- if producer_product == product:
- producer_list.remove(product)
- found_producer = True
- else:
- if self.debug:
- print("[PLACE_ORDER] NEW")
- print("[PLACE_ORDER] Cart: " + str(cart))
- print("[PLACE_ORDER] Producer " + " has now list: " + str(producer_list))
- break
- self.producer_lock.release()
- return cart
|