如何实现分层 api 调用的作业队列?

时间:2021-04-07 11:02:22

标签: php laravel redis laravel-queue amazonsellercentral

我正在与亚马逊销售合作伙伴 api 合作以获取订单数据,但要获取完整数据,我首先需要获取订单并对订单进行 foreach 并将单个订单 ID 传递到不同的端点以获取其他数据,例如买家信息、订单项和地址信息。目前,我在每个请求之间使用 2 秒的睡眠以避免速率限制,每个ordersapi 大约为 1 个请求/秒,整个事情都在 do-while 内,直到 nextToken 不为 null 并且此逻辑在控制器内。我如何为这个进程实现一个redis队列系统来在后台获取数据?我被困在如何在单个作业中分派这些多个请求。我正在使用 clousales api。

    public function handle()
        {
            Redis::throttle('key')->allow(5)->every(1)->then(function () {
                $apiInstance = new \ClouSale\AmazonSellingPartnerAPI\Api\OrdersApi($this->config);
                try {
                    do {
                        $response = $apiInstance->getOrders($this->marketplaceIds, $this->createdAfter, '', '', '', '', '', '', '', '', $this->maxResultsPerPage, '', $this->nextToken, '');
                        $order = (array) $response['payload']['orders'];
                        // print_r($order[0]['amazon_order_id']); die();
    
                        $buyerInfo = $this->apiInstance->getOrderBuyerInfo($order[0]['amazon_order_id']);
            
                        $orderItems = $this->apiInstance->getOrderItems($order[0]['amazon_order_id']);
                    
                        $addressInfo = $this->apiInstance->getOrderAddress($order[0]['amazon_order_id']);
                    
                        if (!ApiCustomer::where('email', $buyerInfo['payload']['buyer_email'])->exists()) {
                            $customer = ApiCustomer::create([
                            'email'               => $buyerInfo['payload']['buyer_email'] ?? '',
                            'customer_first_name' => $buyerInfo['payload']['buyer_name']  ?? '',
                            'customer_last_name'  => '',
                            'telephone'           => '',
                            ]);
                        }
    
                        // print_r($order);
    
                        if ($order[0]['order_status'] == 'Pending') {
                            $order_status = 1;
                        } elseif ($order[0]['order_status'] == 'Unshipped') {
                            $order_status = 2;
                        } elseif ($order[0]['order_status'] == 'Shipped') {
                            $order_status = 5;
                        } elseif ($order[0]['order_status'] == 'Canceled') {
                            $order_status = 7;
                        }
    
                        if (!ApiOrder::where('order_id', $order[0]['amazon_order_id'])->exists()) {
                            $order = ApiOrder::insert([
                            'order_id'     => $order[0]['amazon_order_id'],
                            'order_total'  => $order[0]['order_total']['amount'] ?? 00.0000,
                            'customer_id'  => $customer->id,
                            'channel_id'   => 2,
                            'order_status' => $order_status,
                            'invoice_no'   => '',
                            'created_at'   => Carbon::parse($order[0]['purchase_date']),
                            'updated_at'   => Carbon::parse($order[0]['last_update_date']),
                        ]);
    
                            foreach ($orderItems['payload']['order_items'] as $item) {
                                if (!ApiOrderProduct::where('order_id', $orderItems['payload']['amazon_order_id'])->exists()) {
                                    ApiOrderProduct::create([
                                    'order_id'     => $orderItems['payload']['amazon_order_id'],
                                    'product_id'   => $item['seller_sku'] ?? '',
                                    'quantity'     => $item['quantity_ordered'],
                                  ]);
                                }
                            }
    
                            // For Customer Address Details
                        // foreach ($addressInfo['payload'] as $info) {
                        //     if (!ApiCustomerDetail::where('order_id', $order[0]['amazon_order_id'])->exists() && !ApiCustomerDetail::where('api_customer_id', $customer->id)->exists()) {
                        //         ApiCustomerDetail::create([
                        //             'order_id' => $order[0]['amazon_order_id'],
                        //             'api_customer_id' => $customer->id,
                        //         ]);
                        //     }
                        // }
                        }
    
                        // print_r($order);
                        // print_r($buyerInfo);
                        // print_r($orderItems);
                        // print_r($addressInfo);
                    
                        // sleep(2);
                        // $response = $this->apiInstance->getOrders($marketplace_ids, $created_after, '', '', '', '', '', '', '', '', $max_results_per_page, '', $next_token, '');
                        DB::table('amazon_temp_data')->where('id', 1)->update(['next_token' => $response['payload']['next_token'], 'created_at' => Carbon::now(), 'updated_at' => Carbon::now()]);
                    
                        $this->nextToken = '';
                        if (isset($response['payload']) && isset($response['payload']['next_token'])) {
                            $this->nextToken = $response['payload']['next_token'];
                        }
                    } while ($this->nextToken != '');
                } catch (Exception $e) {
                    Log::info('Exception when calling OrdersV0Api : ', $e->getMessage(), PHP_EOL);
                }
            }, function () {
                return $this->release(2);
            });
        }

我正在初始化构造中的所有内容并从控制器中分派

AmazonRequestsJob::dispatch($marketplace_ids, $max_results_per_page, $created_after, $next_token);

我是队列的新手,所以我不知道我这样做是否正确,因为如果没有队列系统,执行时间会在一段时间后超出。我尝试增加执行时间,但似乎并不理想。

0 个答案:

没有答案