/// <summary>
            /// Processes the customer.
            /// </summary>
            /// <param name="user">The AdWords user.</param>
            /// <param name="customerId">The customer ID.</param>
            /// <param name="query">The report query.</param>
            private void ProcessCustomer(AdWordsUser user, long customerId, string query)
            {
                // Set the customer ID to the current customer.
                this.Config.ClientCustomerId = customerId.ToString();

                string downloadFile = string.Format("{0}{1}adgroup_{2:D10}.gz", this.DownloadFolder,
                                                    Path.DirectorySeparatorChar, customerId);

                // Download the report.
                Console.WriteLine("[Thread #{0}]: Downloading report for customer: {1} into {2}...",
                                  this.ThreadIndex, customerId, downloadFile);

                try
                {
                    ReportUtilities utilities = new ReportUtilities(user, "v201809", query,
                                                                    DownloadFormat.GZIPPED_CSV.ToString());
                    using (ReportResponse response = utilities.GetResponse())
                    {
                        response.Save(downloadFile);
                    }

                    // Mark this report download as success.
                    SuccessfulReportDownload success = new SuccessfulReportDownload
                    {
                        CustomerId = customerId,
                        Path       = downloadFile
                    };
                    SuccessfulReports.TryAdd(success);

                    Console.WriteLine("Report was downloaded to '{0}'.", downloadFile);
                }
                catch (AdWordsReportsException e)
                {
                    // Mark this report download as failure.
                    FailedReportDownload failure = new FailedReportDownload
                    {
                        CustomerId = customerId,
                        Exception  = e
                    };
                    FailedReports.TryAdd(failure);

                    Console.WriteLine(
                        "Failed to download report for customer: {0}. Exception says {1}",
                        customerId, e.Message);
                }
            }
Beispiel #2
0
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="downloadFolder">The file to which the report is downloaded.
        /// </param>
        public void Run(AdWordsUser user, string downloadFolder)
        {
            // Increase the number of HTTP connections we can do in parallel.
            System.Net.ServicePointManager.DefaultConnectionLimit = 100;

            try {
                // Start the rate limiter with an initial value of zero, so that all
                // threads block immediately.
                Semaphore rateLimiter = new Semaphore(0, MAX_REPORT_DOWNLOADS_IN_PARALLEL);

                // Get all the advertiser accounts under this manager account.
                List <long> allCustomerIds = GetDescendantAdvertiserAccounts(user);

                // Create a concurrent queue of customers so that all threads can work
                // on the collection in parallel.
                ConcurrentQueue <long> customerQueue = new ConcurrentQueue <long>(allCustomerIds);

                // Create queues to keep track of successful and failed report downloads.
                ConcurrentQueue <SuccessfulReportDownload> reportsSucceeeded =
                    new ConcurrentQueue <SuccessfulReportDownload>();
                ConcurrentQueue <FailedReportDownload> reportsFailed =
                    new ConcurrentQueue <FailedReportDownload>();

                // Keep an array of events. This is used by the main thread to wait for
                // all worker threads to join.
                ManualResetEvent[] doneEvents = new ManualResetEvent[MAX_NUMBER_OF_THREADS];

                // The list of threads to download reports.
                Thread[] threads = new Thread[MAX_NUMBER_OF_THREADS];

                // The data for each thread.
                ReportDownloadData[] threadData = new ReportDownloadData[MAX_NUMBER_OF_THREADS];

                // The query to be run on each account.
                string query = "SELECT CampaignId, AdGroupId, Impressions, Clicks, Cost from " +
                               "ADGROUP_PERFORMANCE_REPORT where AdGroupStatus IN [ENABLED, PAUSED] " +
                               "DURING LAST_7_DAYS";

                // Initialize the threads and their data.
                for (int i = 0; i < MAX_NUMBER_OF_THREADS; i++)
                {
                    doneEvents[i] = new ManualResetEvent(false);
                    threadData[i] = new ReportDownloadData()
                    {
                        Config            = (AdWordsAppConfig)(user.Config.Clone()),
                        DownloadFolder    = downloadFolder,
                        SignalEvent       = doneEvents[i],
                        ThreadIndex       = i,
                        QuotaLock         = rateLimiter,
                        CustomerIdQueue   = customerQueue,
                        SuccessfulReports = reportsSucceeeded,
                        FailedReports     = reportsFailed
                    };

                    threads[i] = new Thread(threadData[i].ThreadCallback);
                }

                // Start the threads. Since the initial value of rate limiter is zero,
                // all threads will block immediately.
                for (int i = 0; i < threads.Length; i++)
                {
                    threads[i].Start(query);
                }

                // Now reset the rate limiter so all threads can start downloading reports.
                rateLimiter.Release(MAX_REPORT_DOWNLOADS_IN_PARALLEL);

                // Wait for all threads in pool to complete.
                WaitHandle.WaitAll(doneEvents);
                Console.WriteLine("Download completed, results:");

                Console.WriteLine("Successful reports:");
                while (!reportsSucceeeded.IsEmpty)
                {
                    SuccessfulReportDownload success = null;
                    if (reportsSucceeeded.TryDequeue(out success))
                    {
                        Console.WriteLine("Client ID: {0}, Path: {1}", success.CustomerId, success.Path);
                    }
                }

                Console.WriteLine("Failed reports:");
                while (!reportsFailed.IsEmpty)
                {
                    FailedReportDownload failure = null;
                    if (reportsFailed.TryDequeue(out failure))
                    {
                        Console.WriteLine("Client ID: {0}, Cause: {1}", failure.CustomerId,
                                          failure.Exception.Message);
                    }
                }

                Console.WriteLine("All reports are downloaded.");
            } catch (Exception e) {
                throw new System.ApplicationException("Failed to download reports.", e);
            }
        }