使用BatchRequest通过Google Classroom API添加许多课程时收到错误消息“操作被中止”

问题描述 投票:0回答:1

我正在尝试构建一个小的脚本,可以在Google课堂中添加许多课程。

我正在为此使用C#,并且使用了以下2个引用来使我开始这样做:

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

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

[当我使用API​​逐一添加它们时,它确实可以正常工作,没有任何问题,但是,当我尝试使用上面链接中指示的BatchRequest方法时,我开始出错。

首先,假设我要添加一组50个类,当我运行代码时,仅添加了3个或4个类,然后我收到其余的错误消息。

错误仅如下图所示……

enter image description here

我不知道这是怎么回事,我无法理解其原因...

下面是我正在使用的代码:

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这么慢?

谢谢!

google-api google-api-dotnet-client google-classroom
1个回答
0
投票

@@ Bluescrod在创建批处理课程时,您还有问题吗?现在,我还有409个“操作已中止”。使用API​​进行4到7次重复调用,一一对应500个“遇到内部错误”错误。

这是我在打字稿中的代码:

 dtos = [
    {
      uniqueName: 'p:day108.01.1951.catherine',
      descriptionHeading: '',
      name: 'class1'
    },
    {
      uniqueName: 'p:day108.01.1455.july01',
      descriptionHeading: '',
      name: 'class2'
    },
    {
      uniqueName: 'p:day108.01.5649.julielee',
      descriptionHeading: '',
      name: 'class3'
    },
    {
      uniqueName: 'p:day108.01.2136.litda609',
      descriptionHeading: '',
      name: 'class4'
    },
    {
      uniqueName: 'p:day108.01.1894.amyc7591',
      descriptionHeading: '',
      name: 'class5'
    },
    {
      uniqueName: 'p:day108.01.1501.chuoii',
      descriptionHeading: '',
      name: 'class6'
    },
  ];

  createCourses(dtos);

  createCourses(dtos: CourseCreateDTO[]): Observable<ResultSummary> {
    return from(dtos).pipe(
      mergeMap(dto => {
        return this.classroomService.createCourse(dto).pipe(
          map(result => {
            if (!(result instanceof StandardError)) {
              const course: GoogleClassroomCourse = result;
              this.courses.push(course);
              this.coursesChanged.emit();
            }
            return result;
          }),
        );
      }),
      toArray(),
      ResultSummary.resultSummaryForArrayWithStandardError(),
      defaultIfEmpty({} as ResultSummary),
    );
  }

   createCourse(dto: CourseCreateDTO)
    : Observable<GoogleClassroomCourse | StandardError> {
    try {
      // set up http options
      const httpOptions = {
        headers: new HttpHeaders({
          'Content-Type': 'application/json',
          Authorization: 'Bearer ' + this.auth.accessToken
        }),
        // params: params,
        body: {
          id: dto.uniqueName,
          name: dto.name,
          descriptionHeading: dto.descriptionHeading,
          ownerId: ADMIN_USERNAME + '@' + DOMAIN_NAME, 
          courseState: CourseStateEnum.ACTIVE,
        }
      };
      const url = 'https://classroom.googleapis.com/v1/courses';
      return this.http.request<GoogleClassroomCourse>('POST', url, httpOptions).pipe(
        map((result: GoogleClassroomCourse | StandardError) => {
          console.log('result', result);
          if (!(result instanceof StandardError)) {
            return {
              ...result,
              courseData: this.extractCourseData(result)
            } as GoogleClassroomCourse;
          }
          return result;
        }),
      );
    } catch (error) {
      console.log('error', error);
      return of(new StandardError(error.message, dto));
    }
  }

© www.soinside.com 2019 - 2024. All rights reserved.