Получение ошибки «Операция была прервана» при использовании BatchRequest для добавления многих курсов с Google Classroom API - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь создать небольшой скрипт, который может добавить много курсов в Google Classroom.

Я использую C# для этого, и я использовал следующие 2 ссылки, чтобы начать это:

https://developers.google.com/classroom/guides/manage-courses

https://developers.google.com/classroom/guides/batch

Когда я добавляю их один за другим с помощью API, он работает очень хорошо и без каких-либо проблем, однако, когда я пытаюсь использовать метод BatchRequest, как указано в ссылке выше, я начинаю неправильно понимать go.

Прежде всего давайте предположим, что я добавляю набор из 50 классы, когда я запускаю код, только 3 или 4 из них добавляются, тогда я получаю сообщение об ошибке для остальных.

Ошибка только, как показано ниже на рисунке ...

enter image description here

Я понятия не имею, о чем это, и я не могу понять причину этого ...

Ниже приведен код, который я ' m с помощью:

using Google.Apis.Classroom.v1;
using Google.Apis.Classroom.v1.Data;
using Google.Apis.Requests;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace GSuite_ClassroomManager
{
    class Program
    {
        // If modifying these scopes, delete your previously saved credentials
        // at ~/.credentials/classroom.googleapis.com-dotnet-quickstart.json
        static string[] Scopes = { ClassroomService.Scope.ClassroomCourses };
        static string ApplicationName = "Classroom API .NET Quickstart";

        static void Main(string[] args)
        {
            //StartMultipleThread();
            buildCourses();
        }

        static void buildCourses()
        {
            //UserCredential credential;
            string Exepath = System.Reflection.Assembly.GetExecutingAssembly().Location;
            string currDirectory = System.IO.Path.GetDirectoryName(Exepath);
            string jsonFile = currDirectory + @"\credentials.json";
            var credential = GoogleCredential.FromFile(jsonFile).CreateScoped(Scopes).CreateWithUser("me");
            var courses = new List<Course>();
            Console.WriteLine(DateTime.Now.ToString() + " - Authorized successfully...");
            // Create Classroom API service.
            var service = new ClassroomService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = ApplicationName,
            });


            for (var counter=0; counter < 50; counter++)
            {
                CourseAlias alias = new CourseAlias
                {
                    Alias = "d:test0018"+counter.ToString()
                };

                var body = new Course
                {
                    Name = "Test course new 18 "+counter.ToString(),
                    Id = alias.Alias,
                    OwnerId = "me",
                    DescriptionHeading = "Welcome to Test course new " + counter.ToString()+"!",
                    Description = "This is a testing course number " + counter.ToString(),
                    CourseState = "ACTIVE"
                };

                //Console.WriteLine(DateTime.Now.ToString() + " - Creating Test course 3...");
                courses.Add(body);

                //alias = service.Courses.Aliases.Create(alias, body.Id).Execute();
            }

            var batch = new BatchRequest(service, "https://classroom.googleapis.com/batch");
            BatchRequest.OnResponse<Course> callback = (course,error,i,message) =>
            {
                if (error != null)
                {
                    Console.WriteLine(DateTime.Now.ToString() + " - Failed to create new course with the following error..: {0}", error.Message);
                }
                //else
                //{
                //Console.WriteLine(DateTime.Now.ToString() + " - Created new course: {0} with ID {1}, and alias of {2}...", course.Name, course.Id, course.Id);
                //}
            };
            foreach (var course in courses)
            {
                var item = new Course
                {
                    Name = course.Name,
                    Id = course.Id,
                    OwnerId = course.OwnerId,
                    DescriptionHeading = course.DescriptionHeading,
                    Description = course.Description,
                    CourseState = course.CourseState
                };
                var result = service.Courses.Create(item);
                batch.Queue<Course>(result, callback);
                //Console.WriteLine(DateTime.Now.ToString() + " - Created new course: {0} with ID {1}, and alias of {2}...", result.Name, result.Id, course.Id);
            }

            Task.WaitAll(batch.ExecuteAsync());

            Console.WriteLine(DateTime.Now.ToString() + " - Retrieving list of courses");
            // Define request parameters.
            CoursesResource.ListRequest request = service.Courses.List();
            request.PageSize = 100;

            // List courses.
            ListCoursesResponse response = request.Execute();
            Console.WriteLine(DateTime.Now.ToString() + " - Listing courses:");
            if (response.Courses != null && response.Courses.Count > 0)
            {
                foreach (var course in response.Courses)
                {
                    Console.WriteLine("{0} ({1})", course.Name, course.Id);
                }
            }
            else
            {
                Console.WriteLine(DateTime.Now.ToString() + " - No courses found.");
            }
            Console.WriteLine(DateTime.Now.ToString() + " - Done.");
            Console.Read();
        }
     }
}

Я пытался решить эту проблему, однако я не получил никакого результата. Я знаю об ограничении в 1000 запросов для этого, однако я выполняю только 50, и максимум я получил до 300 курсов, которые можно добавить только ...

Я авторизован должным образом и могу создавать курсы, когда использую нормальный метод один за другим, однако при большом количестве курсов, которые у меня есть, он будет проходить вечно, если я не использую партии ...

Могу ли я что-нибудь сделать, чтобы устранить неполадки и выяснить, что происходит на?

РЕДАКТИРОВАТЬ - поэтому я изменил код и использовал 5 потоков, чтобы делать вызовы и добавлять курсы, но процесс все еще очень медленный и идет со скоростью, как будто я просто циклически элементы по одному ...

Это новый код для потоков:

    static private void buildCourses()
        {
            //UserCredential credential;
            string Exepath = System.Reflection.Assembly.GetExecutingAssembly().Location;
            string currDirectory = System.IO.Path.GetDirectoryName(Exepath);
            string jsonFile = currDirectory + @"\credentials.json";
            var credential = GoogleCredential.FromFile(jsonFile).CreateScoped(Scopes).CreateWithUser("me");
            var courses = new List<Course>();
            Console.WriteLine(DateTime.Now.ToString() + " - Authorized successfully...");
            // Create Classroom API service.
            var service = new ClassroomService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = ApplicationName,
            });


            for (var counter=0; counter < 500; counter++)
            {
                CourseAlias alias = new CourseAlias
                {
                    Alias = "d:test0476"+counter.ToString()
                };

                var body = new Course
                {
                    Name = "Test course new 476 "+counter.ToString(),
                    Id = alias.Alias,
                    OwnerId = "me",
                    DescriptionHeading = "Welcome to Test course new " + counter.ToString()+"!",
                    Description = "This is a testing course number " + counter.ToString(),
                    CourseState = "ACTIVE"
                };

                courses.Add(body);
            }


            var itemsCout = courses.Count;
            var threadCount = 5;
            Thread thread1 = new Thread(() =>
            {
                Console.WriteLine("Started thread {0}", (0 + 1).ToString());
                for (var i = 0; i < itemsCout; i = i + threadCount)
                {
                    var item = new Course
                    {
                        Name = courses[i].Name,
                        Id = courses[i].Id,
                        OwnerId = courses[i].OwnerId,
                        DescriptionHeading = courses[i].DescriptionHeading,
                        Description = courses[i].Description,
                        CourseState = courses[i].CourseState
                    };

                    var alias = courses[i].Id;

                    item = service.Courses.Create(item).Execute();
                    Console.WriteLine(DateTime.Now.ToString() + " - Created new course: {0} with ID {1}, and alias of {2}...", item.Name, item.Id, alias);
                }
            });

            Thread thread2 = new Thread(() =>
            {
                Console.WriteLine("Started thread {0}", (1 + 1).ToString());
                for (var i = 1; i < itemsCout; i = i + threadCount)
                {
                    var item = new Course
                    {
                        Name = courses[i].Name,
                        Id = courses[i].Id,
                        OwnerId = courses[i].OwnerId,
                        DescriptionHeading = courses[i].DescriptionHeading,
                        Description = courses[i].Description,
                        CourseState = courses[i].CourseState
                    };

                    var alias = courses[i].Id;

                    item = service.Courses.Create(item).Execute();
                    Console.WriteLine(DateTime.Now.ToString() + " - Created new course: {0} with ID {1}, and alias of {2}...", item.Name, item.Id, alias);
                }
            });

            Thread thread3 = new Thread(() =>
            {
                Console.WriteLine("Started thread {0}", (2 + 1).ToString());
                for (var i = 2; i < itemsCout; i = i + threadCount)
                {
                    var item = new Course
                    {
                        Name = courses[i].Name,
                        Id = courses[i].Id,
                        OwnerId = courses[i].OwnerId,
                        DescriptionHeading = courses[i].DescriptionHeading,
                        Description = courses[i].Description,
                        CourseState = courses[i].CourseState
                    };

                    var alias = courses[i].Id;

                    item = service.Courses.Create(item).Execute();
                    Console.WriteLine(DateTime.Now.ToString() + " - Created new course: {0} with ID {1}, and alias of {2}...", item.Name, item.Id, alias);
                }
            });

            Thread thread4 = new Thread(() =>
            {
                Console.WriteLine("Started thread {0}", (3 + 1).ToString());
                for (var i = 3; i < itemsCout; i = i + threadCount)
                {
                    var item = new Course
                    {
                        Name = courses[i].Name,
                        Id = courses[i].Id,
                        OwnerId = courses[i].OwnerId,
                        DescriptionHeading = courses[i].DescriptionHeading,
                        Description = courses[i].Description,
                        CourseState = courses[i].CourseState
                    };

                    var alias = courses[i].Id;

                    item = service.Courses.Create(item).Execute();
                    Console.WriteLine(DateTime.Now.ToString() + " - Created new course: {0} with ID {1}, and alias of {2}...", item.Name, item.Id, alias);
                }
            });

            Thread thread5 = new Thread(() =>
            {
                Console.WriteLine("Started thread {0}", (4 + 1).ToString());
                for (var i = 4; i < itemsCout; i = i + threadCount)
                {
                    var item = new Course
                    {
                        Name = courses[i].Name,
                        Id = courses[i].Id,
                        OwnerId = courses[i].OwnerId,
                        DescriptionHeading = courses[i].DescriptionHeading,
                        Description = courses[i].Description,
                        CourseState = courses[i].CourseState
                    };

                    var alias = courses[i].Id;

                    item = service.Courses.Create(item).Execute();
                    Console.WriteLine(DateTime.Now.ToString() + " - Created new course: {0} with ID {1}, and alias of {2}...", item.Name, item.Id, alias);
                }
            });

            thread1.Start();
            thread2.Start();
            thread3.Start();
            thread4.Start();
            thread5.Start();

            thread1.Join();
            thread2.Join();
            thread3.Join();
            thread4.Join();
            thread5.Join();

            Console.WriteLine(DateTime.Now.ToString() + " - Done.");
            Console.Read();
        }

Есть ли какой-нибудь способ ускорить это? Или просто API такой медленный?

Спасибо всем!

...