def replyACK(ackToSend, sock): replyToWorld = wa.ACommands() replyToWorld.acks.append(ackToSend) reply = replyToWorld.SerializeToString() _EncodeVarint(sock.send, len(reply), None) sock.send(reply) return
def send_to_world_load(world_socket, packed): cmd = world_amazon_pb2.ACommands() load = world_amazon_pb2.APutOnTruck() conn = connect_db() cursor = conn.cursor() cursor.execute(""" SELECT shipid, truck_id FROM truck_arrive """) tuple = cursor.fetchone() print("shipid: ") print(tuple[0]) print("truck_id: ") print(tuple[1]) # cursor.execute(""" # SELECT whid From packed WHERE shipid = %s # """, [tuple[0]]) seqnum = packed.seqnum load.whnum = 1 load.truckid = tuple[1] load.shipid = tuple[0] load.seqnum = seqnum + 1 cmd.load.append(load) cmd.disconnect = False send_to_world(world_socket, cmd)
def packProduct(worldSock, products, whnum, conn): print(f"Sending pack to world...") cursor = conn.cursor() pack = wa.APack() pack.whnum = whnum for item in products.things: product = wa.AProduct() product = pack.things.add() product.id = item.id product.description = item.description product.count = item.count #print(f"{item.description} stock -{item.count}") sql = '''UPDATE website_stock SET stock = stock - %s WHERE warehouse_id = %s AND product_id = %s;''' cursor.execute(sql, (item.count, whnum, item.id)) conn.commit() #print("-stock update") pack.shipid = products.orderid pack.seqnum = getSeq_num() pack_command = wa.ACommands() pack_command.topack.append(pack) send_pack = sendMessage(worldSock, pack_command) print(pack_command) print(f"sent to the world") pack_response = waitACK(pack.seqnum, send_pack, worldSock) print(f"receive from the world") print(pack_response) packed = responseFromWorld(worldSock) print(packed) for p in packed.ready: replyACK(p.seqnum, worldSock)
def create_acks_msg_in_batch(self, field): command = wapb.ACommands() for i in range(len(field)): command.acks.append(field[i].seqnum) data_msg = command.SerializeToString() return data_msg
def trucks_handler(alltruckreadies): order_id = alltruckreadies.packageid try: cur = conn.cursor() print("enter truck handler") cur.execute("SELECT warehouse_id FROM AmazonWeb_order WHERE id = %s;",([order_id])) command = world_amazon.ACommands() #command.simspeed = SPEED load_package = command.load.add() row = cur.fetchall() whNum = row[0][0] print("warehouse number is: ", whNum) load_package.whnum = whNum print("shipid is: ", order_id) load_package.shipid = order_id print("SEQ is: ", SEQ) load_package.seqnum = SEQ SEQPLUS() load_package.truckid = alltruckreadies.truckid #update order database, set the truck id print("update to in deliver") cur.execute("UPDATE AmazonWeb_order SET truck_id = %s WHERE id = %s;",(alltruckreadies.truckid, order_id)) #send message to world to start loading print("ask world to start loading") send_msg(command, WORLD_SOCKET) except (Exception, psycopg2.DatabaseError) as error: print(error)
def arrive_handler(arrive): send_world_ack(arrive) try: cur = conn.cursor() #if products purchase has arrived, then we start processing these orders print("in prorgess") cur.execute("SELECT id FROM AmazonWeb_order WHERE status = 'in progress';") rows = cur.fetchall() for row in rows: cur.execute("SELECT products_id, quantity, warehouse_id FROM AmazonWeb_order WHERE id = %s;",(row)) info = cur.fetchone() cur.execute("SELECT name, description FROM AmazonWeb_product WHERE id = %s;",([info[0]])) detail = cur.fetchone() command = world_amazon.ACommands() #command.simspeed = SPEED myorder = command.topack.add() myorder.shipid = row[0] myorder.whnum = info[2] myorder.seqnum = SEQ SEQPLUS() mythings = myorder.things.add() mythings.id = info[0] mythings.description = detail[1] mythings.count = info[1] #send msg to world, ask for start packing send_msg(command, WORLD_SOCKET) cur.execute("UPDATE AmazonWeb_order SET status = 'packing' WHERE id = %s;", (row)) conn.commit() cur.close() except (Exception, psycopg2.DatabaseError) as error: print(error)
def ack_back_world(world_socket, seqNum): world_command = world_amazon_pb2.ACommands() world_command.acks.append(seqNum) print("---------------- ACK back to world ------------") my_send(world_socket, world_command) print(world_command) print("-----------------------------------------------")
def tobuy(order_id): #whnum = order_id % TOTALL_WHNUM try: cur = conn.cursor() #get the orderid, productsid, amount and warehouseid print("start selecting order tobuy") cur.execute("SELECT id, products_id, quantity, warehouse_id FROM AmazonWeb_order WHERE id = %s",([order_id])) row = cur.fetchone() order_id = row[0] amount = row[2] #get the name and description from product cur.execute("SELECT name,description FROM AmazonWeb_Product WHERE id = %s",([row[1]])) detail = cur.fetchone() name = detail[0] description = detail[1] command = world_amazon.ACommands() #command.simspeed = SPEED BUY = command.buy.add() BUY.whnum = row[3] BUY.seqnum = SEQ SEQPLUS() allproducts = BUY.things.add() allproducts.id = row[1] allproducts.description = description allproducts.count = amount send_msg(command, WORLD_SOCKET) print("after purchase more") #shouldn'e get truck here, should get truck after packed #get_truck(order_id) conn.commit() cur.close() except (Exception, psycopg2.DatabaseError) as error: print(error)
def load_helper(world_sock, amazon_db, shipid): c = amazon_db.cursor() c.execute("SELECT * FROM main_order WHERE id = {0};".format(shipid)) the_order = c.fetchone() cm = world_amazon_pb2.ACommands() #print("SHIPID: " + str(shipid)) print(the_order) print("TRUCK_ID:", the_order[9]) load = cm.load.add() load.whnum = 1 load.truckid = the_order[9] load.shipid = shipid global seqnum load.seqnum = seqnum global ack_set tmp_seqnum = seqnum while True: send_message(world_sock, cm) time.sleep(3) if tmp_seqnum in ack_set: break print("still sending msg in load_helper") seqnum += 1 c.execute( "UPDATE main_order SET s_status = 'loading' WHERE id = {0};".format( shipid)) ###########currently assume world absolutely return ack amazon_db.commit() c.close()
def recvHandler(world_sock, amazon_db): global ack_set while 1: ackflag = False recv_msg = get_message(world_sock, world_amazon_pb2.AResponses) cm_ack = world_amazon_pb2.ACommands() for APurchasemore_resp in recv_msg.arrived: arrived_helper(world_sock, amazon_db, APurchasemore_resp) cm_ack.acks.append(APurchasemore_resp.seqnum) ackflag = True for APacked_resp in recv_msg.ready: ready_helper(world_sock, amazon_db, APacked_resp) cm_ack.acks.append(APacked_resp.seqnum) ackflag = True for ALoaded_resp in recv_msg.loaded: loaded_helper(world_sock, amazon_db, ALoaded_resp) cm_ack.acks.append(ALoaded_resp.seqnum) ackflag = True for ack_obj in recv_msg.acks: ack_set.add(ack_obj) print("FOR DEBUGGING ACK_SET:") print(ack_set) # send acks to world if ackflag: send_message(world_sock, cm_ack) if recv_msg.error: print("Something wrong!") if recv_msg.finished: print("close world connection") world_sock.close()
def generate_buy(conn): cursor = conn.cursor() # append purchase more Acommand to the global dict toWorld # fetch one product that is not enough in the warehouse sql = '''SELECT item_id,item_name FROM amazon_web_order WHERE is_enough = FALSE;''' cursor.execute(sql) buying_product = cursor.fetchone() if buying_product: print("Generate APurchaseMore") # calculate the number of this particular product we need to buy from the world # update the is_enough field to true sql = '''SELECT pkgid, purchase_num FROM amazon_web_order WHERE is_enough = FALSE AND item_id = %s;''' cursor.execute(sql, (buying_product[0],)) wh_purchase_num = 0 orders = cursor.fetchall() for order in orders: wh_purchase_num += order[1] sql = '''UPDATE amazon_web_order SET is_enough = TRUE WHERE pkgid = %s;''' cursor.execute(sql, (order[0],)) conn.commit() # generate ACommands Acmd = world_amazon_pb2.ACommands() Acmd.disconnect = False tobuy = Acmd.buy.add() tobuy.whnum = 1 # we only have one warehouse currently tobuy.seqnum = seq_num item = tobuy.things.add() item.id = buying_product[0] item.description = buying_product[1] item.count = wh_purchase_num # buy exactly the orders need return Acmd return None
def start_loading(world_socket, order_id, truck_id): print("Entered start_loading()") command = world.ACommands() load = command.load.add() seqnum = generate_seqnum_and_add_to_waiting_ack_set() load.seqnum = seqnum try: conn, cursor = connect_db() query = f""" SELECT warehouse_id FROM amazon_frontend_order WHERE id={order_id} """ cursor.execute(query) load.whnum = cursor.fetchone()[0] load.truckid = truck_id load.shipid = order_id cursor.close() except (Exception, psycopg2.DatabaseError) as error: print(error) update_order_status(order_id, order_status.LOADING) resend_to_world_until_ack_received(command, seqnum, world_socket) print("Exited start_loading()")
def pack_product(world_socket, bought): cmd = world_amazon_pb2.ACommands() pack = world_amazon_pb2.APack() shipid = FIFO.pop(0) seqnum = bought.seqnum + 1 whnum = bought.whnum product = world_amazon_pb2.AProduct() for thing in bought.things: product.id = thing.id product.description = thing.description product.count = thing.count pack.whnum = whnum pack.things.append(product) pack.shipid = shipid pack.seqnum = seqnum cmd.disconnect = False cmd.topack.append(pack) send_to_world(world_socket, cmd) conn = connect_db() cursor = conn.cursor() for thing in bought.things: #cursor.execute("""SET IDENTITY_INSERT packed ON""") cursor.execute( """ Insert INTO packed (whid, item_id, seqnum, isRead) VALUES (%s,%s,%s,%s) """, [whnum, product.id, generate_seqnum_ups(), 0]) conn.commit() cursor.close()
def generate_query(order): print("Generate AQuery") Acmd = world_amazon_pb2.ACommands() Acmd.disconnect = False query = Acmd.queries.add() query.packageid = order[0] query.seqnum = seq_num return Acmd
def reply_ack_to_world_with_lock(response_from_world, world_socket): ''' Send ack to world once, thread-safe ''' command = world.ACommands() command.acks.append(response_from_world.seqnum) global WORLD_WRITER_MUTEX with WORLD_WRITER_MUTEX: send_request(command, world_socket)
def generate_load(order): print("Generate APutOnTruck") Acmd = world_amazon_pb2.ACommands() Acmd.disconnect = False toload = Acmd.load.add() toload.whnum = 1 toload.truckid = order[1] toload.shipid = order[0] toload.seqnum = seq_num return Acmd
def purchaseMore(product_message, worldSock, conn): cursor = conn.cursor() purchaseFromWH = wa.ACommands() purchase = purchaseFromWH.buy.add() whnum = SEQ_NUM % 5 + 1 # random warehouse from 1 to 5 PMflag = 0 for _product in product_message.things: productID = _product.id sql = '''SELECT stock FROM website_stock WHERE warehouse_id = %s AND product_id = %s;''' cursor.execute(sql, (whnum, productID)) curr_stock = cursor.fetchone()[0] count = _product.count thing = purchase.things.add() thing.id = _product.id thing.description = _product.description if (curr_stock <= count): # purchase more PMflag = 1 thing.count = _product.count + 100 else: thing.count = _product.count if PMflag == 1: # as long as one product does not have enough stock, purchase all # not enough: purchase count+100 # enough: purchase count # else directly return to call truck purchase.seqnum = getSeq_num() purchase.whnum = whnum WAIT_ACK_QUEUE.append(purchase.seqnum) sendToWorld = sendMessage(worldSock, purchaseFromWH) order_id = product_message.orderid print(f"{order_id} purchase sent") print(purchase.seqnum) print("send world PurchaseMore") world_response = waitACK(purchase.seqnum, sendToWorld, worldSock) print("world responded") print(world_response) for PMresponse in world_response.arrived: for item in PMresponse.things: print(f"{item.description} stock +{item.count}") sql = '''UPDATE website_stock SET stock = stock + %s WHERE warehouse_id = %s AND product_id = %s;''' cursor.execute(sql, (item.count, whnum, item.id)) conn.commit() print("+stock update") worldPMseq = PMresponse.seqnum print(f"world purchase more seq is {worldPMseq}") replyACK(worldPMseq, worldSock) print(f"send {worldPMseq} to world!") return whnum
def send_world_requests(world_sock, world_comm_data): pb_dict = world_comm_data.unacked_protobuf_dict command_pb = wapb2.ACommands() command_pb.buy.extend(pb_dict['APurchaseMore'].values()) command_pb.topack.extend(pb_dict['APack'].values()) command_pb.load.extend(pb_dict['APutOnTruck'].values()) command_pb.queries.extend(pb_dict['AQuery'].values()) command_pb.acks.extend(world_comm_data.pop_all_acks()) print("sending to world:-------------------", command_pb) print("------") send_pbuf(world_sock, command_pb)
def create_put_on_truck_msg(self, warehouse_id, truckid, shipid, seqnum): put_on_truck_msg = wapb.APutOnTruck() put_on_truck_msg.whnum = warehouse_id put_on_truck_msg.truckid = truckid put_on_truck_msg.shipid = shipid put_on_truck_msg.seqnum = seqnum command = wapb.ACommands() command.load.append(put_on_truck_msg) # command.simspeed = cfg.simulate_speed data_msg = command.SerializeToString() return data_msg
def create_purchase_more_msg(self, warehouse_id, product_id, description, count, seqnum): product = self.prepare_product(product_id, description, count) purchase = wapb.APurchaseMore() purchase.whnum = warehouse_id purchase.things.append(product) purchase.seqnum = seqnum command = wapb.ACommands() command.buy.append(purchase) # command.simspeed = cfg.simulate_speed data_msg = command.SerializeToString() return data_msg
def generate_pack(order): print("Generate APack") Acmd = world_amazon_pb2.ACommands() Acmd.disconnect = False topack = Acmd.topack.add() topack.whnum = 1 topack.shipid = order[0] topack.seqnum = seq_num item = topack.things.add() item.id = order[8] item.description = order[7] item.count = order[9] return Acmd
def world_buy(world_socket, whnum, purchase_list, world_acks): seqnum = next(gen) # repeated APurchaseMore buy = 1; world_command = world_amazon_pb2.ACommands() go_buy = world_command.buy.add() go_buy.whnum = whnum go_buy.seqnum = seqnum for item in purchase_list: product_command = go_buy.things.add(id=item['item_id'], description=item['description'], count=item['count']) world_command.simspeed = SIMSPEED send_world(world_socket, world_command, seqnum, world_acks)
def send_ACommands(sock): cm = world_amazon_pb2.ACommands() # buy case buy = cm.buy.add() buy.whnum = 1 buy.seqnum = 1 product = buy.things.add() product.id = 1 product.description = "basketball" product.count = 10 send_message(sock, cm)
def test(): cmd = world_amazon_pb2.ACommands() cmd.disconnect = False cmd.acks.append(0) purchase_more = world_amazon_pb2.APurchaseMore() product = world_amazon_pb2.AProduct() product.id = 1 product.description = "Ipad" product.count = 100 purchase_more.whnum = 1 purchase_more.things.append(product) purchase_more.seqnum = 2 cmd.buy.append(purchase_more) return cmd
def topack_helper(world_sock, amazon_db, shipid): c = amazon_db.cursor() #print("shipid is: " + str(shipid)) c.execute( "SELECT bought_quantity, item_id_id FROM main_order WHERE id = {0};". format(shipid)) the_order_c = c.fetchone() cm = world_amazon_pb2.ACommands() topack = cm.topack.add() topack.whnum = 1 topack.shipid = shipid global seqnum topack.seqnum = seqnum order = topack.things.add() order_item_id = the_order_c[1] c.execute("SELECT name, quantity FROM main_item WHERE id = {0};".format( order_item_id)) item = c.fetchone() item_name = item[0] item_quant = item[1] order.id = order_item_id order.description = item_name order.count = the_order_c[0] #bought_quantity c.execute("UPDATE main_item SET quantity = {0} WHERE id = {1};".format( item_quant - the_order_c[0], order_item_id)) print("FOR TEST item_quant: " + str(item_quant)) print("FOR TEST the_order_c[0]: " + str(the_order_c[0])) print("FOR TEST item_quant - the_order_c[0]: " + str(item_quant - the_order_c[0])) # try really fast simspeed # cm.simspeed = 99999 global ack_set tmp_seqnum = seqnum while True: send_message(world_sock, cm) time.sleep(3) if tmp_seqnum in ack_set: break print("still sending msg in topack_helper") seqnum += 1 c.execute( "UPDATE main_order SET s_status = 'packing' WHERE id = {0};".format( shipid)) ###########currently assume world absolutely return ack amazon_db.commit() c.close()
def start_packing(world_socket, order_id): print("Entered start_packing()") command = world.ACommands() pack = command.topack.add() seqnum = generate_seqnum_and_add_to_waiting_ack_set() pack.seqnum = seqnum try: conn, cursor = connect_db() query = f""" SELECT product_id, description, num_product FROM amazon_frontend_orderproducttuple, amazon_frontend_product WHERE amazon_frontend_orderproducttuple.product_id=amazon_frontend_product.id AND amazon_frontend_orderproducttuple.order_id={order_id} """ cursor.execute(query) rows = cursor.fetchall() for row in rows: thing = pack.things.add() thing.id = row[0] thing.description = row[1] thing.count = row[2] query = f""" SELECT warehouse_id FROM amazon_frontend_order WHERE id={order_id} """ cursor.execute(query) pack.whnum = cursor.fetchone()[0] pack.shipid = order_id # Update warehouse stock query = "" for thing in pack.things: query += f""" UPDATE amazon_frontend_warehousestock SET num_product=num_product-{thing.count} WHERE warehouse_id={pack.whnum} AND product_id={thing.id}; """ execute_and_commit(query, conn, cursor) cursor.close() except (Exception, psycopg2.DatabaseError) as error: print(error) update_order_status(order_id, order_status.PACKING) resend_to_world_until_ack_received(command, seqnum, world_socket)
def loadProduct(worldSock, product, truck_id, whnum): load = wa.APutOnTruck() load.whnum = whnum load.truckid = truck_id load.shipid = product.orderid load.seqnum = getSeq_num() load_command = wa.ACommands() load_command.load.append(load) send_load = sendMessage(worldSock, load_command) print(load_command) print(f"sent to the world") load_response = waitACK(load.seqnum, send_load, worldSock) print(load_response) loaded = responseFromWorld(worldSock) print(loaded) replyACK(load.seqnum, worldSock)
def create_pack_msg(self, warehouse_id, product_ids, descriptions, counts, shipid, seqnum): assert len(product_ids) == len(descriptions) == len(counts) pack = wapb.APack() pack.whnum = warehouse_id for i in range(len(product_ids)): product = self.prepare_product(product_ids[i], descriptions[i], counts[i]) pack.things.append(product) pack.shipid = shipid pack.seqnum = seqnum command = wapb.ACommands() command.topack.append(pack) # command.simspeed = cfg.simulate_speed data_msg = command.SerializeToString() return data_msg
def world_load(db, world_socket, whnum, truckid, sid_list, world_acks): for sid in sid_list: world_command = world_amazon_pb2.ACommands() seqnum = next(gen) # repeated APutOnTruck load = 3; go_load = world_command.load.add() go_load.whnum = whnum go_load.truckid = truckid go_load.shipid = sid go_load.seqnum = seqnum world_command.simspeed = SIMSPEED # prime functionality prime = q_prime_by_sid(db, sid) if prime: world_command.simspeed = PRIME_SIMSPEED send_world(world_socket, world_command, seqnum, world_acks) # update status to loading update_pkg_status(db, 5, (sid, ))
def handle_web_responses(world_socket, web_socket): conn = connect_db() # num_threads = 100 # excutor = ThreadPoolExecutor(max_workers = num_threads) connection, addr = web_socket.accept() while (1): response = recv_from_web(web_amazon_pb2.Cmd, connection) request = world_amazon_pb2.ACommands() request.disconnect = False for buy in response.buy: conn = connect_db() cursor = conn.cursor() cursor.execute( """ INSERT INTO purchase (product_name,product_id,description,user_name,count, shipid, x, y) VALUES(%s,%s,%s,%s,%s,%s,%s,%s); """, [ buy.description, buy.productid, buy.description, buy.username, buy.count, buy.packageid, buy.x, buy.y ]) conn.commit() cursor.close() FIFO.append(buy.packageid) FI_FO.append(buy.packageid) purchase = world_amazon_pb2.APurchaseMore() purchase.seqnum = generate_seqnum_world() purchase.whnum = 1 thing = world_amazon_pb2.AProduct() thing.id = buy.productid thing.description = buy.description thing.count = buy.count purchase.things.append(thing) request.buy.append(purchase) for query in response.queries: quer = world_amazon_pb2.AQuery() quer.packageid = query.packageid quer.seqnum = generate_seqnum_world() PURCHASED[quer.seqnum] = quer.packageid request.queries.append(quer) send_to_world(world_socket, request)