Пример #1
0
def check_availability_and_purchase(customer, event_sku, qty, tier="General"):
    """Check if there is sufficient inventory before making the purchase"""
    p = redis.pipeline()
    try:
        e_key = keynamehelper.create_key_name("event", event_sku)
        redis.watch(e_key)
        available = int(redis.hget(e_key, "available:" + tier))
        price = float(redis.hget(e_key, "price:" + tier))
        if available >= qty:
            p.hincrby(e_key, "available:" + tier, -qty)
            order_id = generate.order_id()
            purchase = {
                'order_id': order_id,
                'customer': customer,
                'tier': tier,
                'qty': qty,
                'cost': qty * price,
                'event_sku': event_sku,
                'ts': long(time.time())
            }
            so_key = keynamehelper.create_key_name("sales_order", order_id)
            p.hmset(so_key, purchase)
            p.execute()
        else:
            print "Insufficient inventory, have {}, requested {}".format(
                available, qty)
    except WatchError:
        print "Write Conflict check_availability_and_purchase: {}".format(
            e_key)
    finally:
        p.reset()
    print "Purchase complete!"
Пример #2
0
def reservation(event_sku, tier, block_name, first_seat, last_seat):
    """ Reserve the required seats. Create an expiring key (i.e. a latch) to
 reserve each seat. If that is successful, then an XOR can be executed to
 update the seat map, without needed a Watch."""
    reserved = False
    p = redis.pipeline()
    try:
        for i in range(first_seat, last_seat + 1):
            # Reserve individual seat, raise exception is already reserved
            seat_key = keynamehelper.create_key_name("seatres", event_sku,
                                                     tier, block_name, str(i))
            if redis.set(seat_key, True, px=5000, nx=True) != True:
                raise SeatTaken(i, seat_key)
        order_id = generate.order_id()
        required_block = int(math.pow(2, last_seat - first_seat + 1)) - 1 << (
            first_seat - 1)
        vals = ["SET", "u32", 0, required_block]
        res_key = keynamehelper.create_key_name("seatres", event_sku, tier,
                                                block_name, order_id)
        p.execute_command("BITFIELD", res_key, *vals)
        p.expire(res_key, 5)
        block_key = keynamehelper.create_key_name("seatmap", event_sku, tier,
                                                  block_name)
        p.bitop("XOR", block_key, block_key, res_key)
        p.execute()
        reserved = True
    except SeatTaken as error:
        print "Seat Taken/{}".format(error.message)
    finally:
        p.reset()
    return reserved
Пример #3
0
def reserve(customer, event_sku, qty, tier="General"):
    """First reserve the inventory and perform a credit authorization. If successful
then confirm the inventory deduction or back the deducation out."""
    p = redis.pipeline()
    try:
        e_key = keynamehelper.create_key_name("event", event_sku)
        redis.watch(e_key)
        available = int(redis.hget(e_key, "available:" + tier))
        if available >= qty:
            order_id = generate.order_id()
            ts = long(time.time())
            price = float(redis.hget(e_key, "price:" + tier))
            p.hincrby(e_key, "available:" + tier, -qty)
            p.hincrby(e_key, "held:" + tier, qty)
            # Create a hash to store the seat hold information
            hold_key = keynamehelper.create_key_name("ticket_hold", event_sku)
            p.hsetnx(hold_key, "qty:" + order_id, qty)
            p.hsetnx(hold_key, "tier:" + order_id, tier)
            p.hsetnx(hold_key, "ts:" + order_id, ts)
            p.execute()
    except WatchError:
        print "Write Conflict in reserve: {}".format(e_key)
    finally:
        p.reset()
    if creditcard_auth(customer, qty * price):
        try:
            purchase = {
                'order_id': order_id,
                'customer': customer,
                'tier': tier,
                'qty': qty,
                'cost': qty * price,
                'event_sku': event_sku,
                'ts': long(time.time())
            }
            redis.watch(e_key)
            # Remove the seat hold, since it is no longer needed
            p.hdel(
                hold_key,
                "qty:" + order_id,
            )
            p.hdel(hold_key, "tier:" + order_id)
            p.hdel(hold_key, "ts:" + order_id)
            # Update the Event
            p.hincrby(e_key, "held:" + tier, -qty)
            # Post the Sales Order
            so_key = keynamehelper.create_key_name("sales_order", order_id)
            p.hmset(so_key, purchase)
            p.execute()
        except WatchError:
            print "Write Conflict in reserve: {}".format(e_key)
        finally:
            p.reset()
        print "Purchase complete!"
    else:
        print "Auth failure on order {} for customer {} ${}".format(
            order_id, customer, price * qty)
        backout_hold(event_sku, order_id)
Пример #4
0
def purchase(event_sku):
  """Simple purchase function, that pushes the sales order for publishing"""
  qty = random.randrange(1, 10)
  price = 20
  order_id = generate.order_id()
  s_order = {'who': "Jim", 'qty': qty, 'cost': qty * price,
             'order_id': order_id, 'event': event_sku,
             'ts': generate.random_time_today()}
  post_purchases(order_id, s_order)
Пример #5
0
 def create_purchase(self, customer, event, quantity):
     order_id = generate.order_id()
     purchase_key = keynamehelper.create_key_name("sales_order", order_id)
     purchase = {'state':'RESERVE', 'order_id': order_id,
                 'customer_id': customer['id'], 'qty': quantity,
                 'cost':     quantity * float(event['price:General']),
                 'event_sku': event['sku'], 'ts': int(time.time())}
     self.redis.hmset(purchase_key, purchase)
     return purchase_key