示例#1
0
def get_msg_instance(topic,
                     body,
                     keys='',
                     tags='',
                     property=None,
                     delay_time_level=0):
    msg = Message(topic)
    if keys:
        msg.set_keys(keys)
    if tags:
        msg.set_tags(tags)
    if property:
        msg.set_property(property[0], property[1])
    if delay_time_level:
        msg.set_delay_time_level(delay_time_level)
    body = str(body)
    # body = bytes(json.dumps(body),encoding="utf8")
    msg.set_body(body)
    return msg
示例#2
0
    def local_execute(self, msg, user_args):
        msg_body = json.loads(msg.body.decode("utf-8"))
        order_sn = msg_body["orderSn"]
        local_execute_dict[order_sn] = {}
        parent_span = local_execute_dict[msg_body["parent_span_id"]]

        with settings.DB.atomic() as txn:
            goods_ids = []
            goods_nums = {}
            order_amount = 0
            order_goods_list = []
            tracer = opentracing.global_tracer()
            with tracer.start_span("select_shopcart") as select_shopchart_span:
                for cart_item in ShoppingCart.select().where(
                        ShoppingCart.user == msg_body["userId"],
                        ShoppingCart.checked == True):
                    goods_ids.append(cart_item.goods)
                    goods_nums[cart_item.goods] = cart_item.nums
                if not goods_ids:
                    local_execute_dict[order_sn][
                        "code"] = grpc.StatusCode.NOT_FOUND
                    local_execute_dict[order_sn][
                        "detail"] = "No item in shopping cart"
                    return TransactionStatus.ROLLBACK

            # query goods info from goods srv
            with tracer.start_span("query_goods",
                                   child_of=parent_span) as query_goods_span:
                register = consul.ConsulRegister(settings.CONSUL_HOST,
                                                 settings.CONSUL_POST)
                goods_srv_host, goods_srv_port = register.get_host_port(
                    f'Service == "{settings.Goods_srv_name}"')
                if not goods_srv_host or not goods_srv_port:
                    local_execute_dict[order_sn][
                        "code"] = grpc.StatusCode.NOT_FOUND
                    local_execute_dict[order_sn][
                        "detail"] = "Goods service not available"
                    return TransactionStatus.ROLLBACK

                goods_channel = grpc.insecure_channel(
                    f"{goods_srv_host}:{goods_srv_port}")
                goods_stub = goods_pb2_grpc.GoodsStub(goods_channel)
                goods_sell_info = []
                try:
                    goods_rsp = goods_stub.BatchGetGoods(
                        goods_pb2.BatchGoodsIdInfo(id=goods_ids))
                    for good in goods_rsp.data:
                        order_amount += good.shopPrice * goods_nums[good.id]
                        order_goods = OrderGoods(
                            goods=good.id,
                            goods_name=good.name,
                            goods_image=good.goodsFrontImage,
                            goods_price=good.shopPrice,
                            nums=goods_nums[good.id])
                        order_goods_list.append(order_goods)
                        goods_sell_info.append(
                            inventory_pb2.GoodsInvInfo(
                                goodsId=good.id, num=goods_nums[good.id]))
                except grpc.RpcError as e:
                    local_execute_dict[order_sn][
                        "code"] = grpc.StatusCode.INTERNAL
                    local_execute_dict[order_sn]["detail"] = str(e)
                    return TransactionStatus.ROLLBACK
            # prepare half message

            with tracer.start_span("query_inv",
                                   child_of=parent_span) as query_inv_span:
                inventory_host, inventory_port = register.get_host_port(
                    f'Service == "{settings.Inventory_srv_name}"')
                if not inventory_host or not inventory_port:
                    local_execute_dict[order_sn][
                        "code"] = grpc.StatusCode.INTERNA
                    local_execute_dict[order_sn][
                        "detail"] = "Inventory service not available"
                    return TransactionStatus.ROLLBACK
                inventory_channel = grpc.insecure_channel(
                    f"{inventory_host}:{inventory_port}")
                inventory_channel = grpc.intercept_channel(
                    inventory_channel, RetryInterceptor)
                inv_stub = inventory_pb2_grpc.InventoryStub(inventory_channel)
                try:
                    inv_stub.Sell(
                        inventory_pb2.SellInfo(goodsInfo=goods_sell_info,
                                               orderSn=order_sn))
                except grpc.RpcError as e:
                    local_execute_dict[order_sn][
                        "code"] = grpc.StatusCode.INTERNAL
                    local_execute_dict[order_sn]["detail"] = str(e)
                    err_code = e.code()
                    if err_code == grpc.StatusCode.UNKNOWN or grpc.StatusCode.DEADLINE_EXCEEDED:
                        return TransactionStatus.COMMIT
                    else:
                        return TransactionStatus.ROLLBACK

            with tracer.start_span("insert_order",
                                   child_of=parent_span) as insert_order_span:
                try:
                    order = OrderInfo()
                    order.user = msg_body["userId"]
                    order.order_sn = order_sn
                    order.order_amount = order_amount
                    order.address = msg_body["address"]
                    order.signer_name = msg_body["name"]
                    order.singer_mobile = msg_body["mobile"]
                    order.post = msg_body["post"]
                    order.save()
                    for order_goods in order_goods_list:
                        order_goods.order = order.id
                    OrderGoods.bulk_create(order_goods_list)

                    ShoppingCart.delete().where(
                        ShoppingCart.user == msg_body["userId"],
                        ShoppingCart.checked == True).execute()
                    local_execute_dict[order_sn] = {
                        "code": grpc.StatusCode.OK,
                        "detail": "Create order succeeded",
                        "order": {
                            "id": order.id,
                            "orderSn": order_sn,
                            "total": order.order_amount
                        }
                    }
                    #发送延时消息
                    msg = Message("order_timeout")
                    msg.set_delay_time_level(16)
                    msg.set_keys("imooc")
                    msg.set_tags("cancel")
                    msg.set_body(json.dumps({"orderSn": order_sn}))
                    sync_producer = Producer("cancel")
                    sync_producer.set_name_server_address(
                        f"{settings.RocketMQ_HOST}:{settings.RocketMQ_PORT}")
                    sync_producer.start()
                    ret = sync_producer.send_sync(msg)
                    if ret.status != SendStatus.OK:
                        raise Exception("延时消息发送失败")
                    logger.info("发送延时消息时间" + datetime.now())
                    sync_producer.shutdown()
                except Exception as e:
                    txn.rollback()
                    local_execute_dict[order_sn][
                        "code"] = grpc.StatusCode.INTERNA
                    local_execute_dict[order_sn]["detail"] = str(e)
                    return TransactionStatus.COMMIT
            return TransactionStatus.ROLLBACK