实习生聚焦:Utkarsh Jadhav

9 年 2015 月 XNUMX 日 | 作者

我的名字是 Utkarsh Jadhav,我是波士顿东北大学计算机科学专业的硕士生。 过去 XNUMX 周我在 edX 与平台团队一起工作。 平台团队负责构建 Open edX 产品的基础架构,特别是致力于让代码运行得更快。 在这篇文章中,我想重点介绍我的一个主要项目,调用堆栈管理器。 它是一个跟踪函数、方法和 Django 模型类的唯一调用堆栈的工具。

课件学生模块 (CSM) 以及 课件学生模块历史 (CSMH) 在 edx-platform 代码中负责维护学生尝试问题的用户状态和他们各自的成绩。 edx.org 网站最近吸引了 5 万学习者; CSM 和 CSMH 的不断增长的规模正在引起人们对空间和数据库故障的严重担忧。 随着代码库和数据库量的增加,打破 edx 平台中的 LMS 和 CMS 等单一代码区域是一项至关重要的需求。

edX 用户状态客户端 (eUSC)

最初,用户态客户端的结构如下——

以前的用户状态客户端结构显示了 edx 平台和 MySQL 数据库之间通过 CSM/CSMH 进行的通信

以前的用户状态客户端结构显示了 edx 平台和 MySQL 数据库之间通过 CSM/CSMH 进行的通信

整个结构在 edx/edx-平台. 用户状态客户端直接与名为的 MySQL 表通信 课件_学生模块 以及 课件_学生模块历史通过 DjangoORM。

当我开始实习时,团队已经知道这种架构的缺点。 为了解决这个问题,我帮助实现了建议的架构,如下图所示:

用户状态客户端的建议结构显示平台和数据库后端之间的层 edx-user-state-client

用户状态客户端的建议结构显示平台和数据库后端之间的层 edx-user-state-client

在这个新架构中, edx 用户状态客户端 充当 edx 平台和数据库后端之间的一层。 使用这种结构有很多优点:

  1. eUSC 将充当抽象级别上的单个接口,通过该接口对数据库进行所有调用。 这种模式最终将有助于与数据库的有效通信。
  2. eUSC 还将允许在不同后端之间轻松切换。 此 API 将允许选择后端,即使是分布式任务。

作为创建此结构的第一步,我创建了一个名为 edx/edx-用户状态-客户端. 此存储库包含接口 XBlock用户状态客户端,它负责 Django 模型类对数据库的所有调用。

调用堆栈管理器

XBlock用户状态客户端 负责对数据库进行所有调用。 然而,考虑到 edX 代码库的巨大规模、第三方扩展(例如 XBlocks)的使用以及在各个地方对数据库的许多调用,确实值得捕获不是通过接口进行的对数据库的调用 XBlock用户状态客户端.

为了解决这个需求,我开发了一个名为 调用堆栈管理器. 这是一个库,它允许我们跟踪不是通过接口进行的调用,并直接与数据库通信。 调用堆栈管理器将此类调用记录在 LMS 日志中。

该库实现了两个主要的装饰器:

  1. @trackit – 跟踪装饰实体
  2. @不跟踪 - 停止跟踪由装饰的实体 @trackit.

开发这个库的主要需求是跟踪 CSM 和 CSMH 中模型类的调用,主要是 学生模块 以及 学生模块历史. 在 Django 中与数据库的通信是由用户定义的类完成的,这些类是 Django“模型”类. 模型类使用 查询集 API 创建、检索和更新数据库。 可以使用名为的自定义管理器覆盖 QuerySet API 进行的调用 调用堆栈管理器 – 在库调用堆栈管理器中定义。 这样,跟踪直接访问数据库的 Django Model 类的特殊情况就得到了处理。

在初始版本中运行调用堆栈管理器时,我遇到了以下问题:

  1. 通话记录重复制作,使 LMS 日志混乱。
  2. 我们已经知道的许多电话被不必要地记录下来。
  3. 通话记录中包含不需要的帧,使其冗长且难以阅读。

为了解决这些问题,我引入了一个新的装饰器,名为 @不跟踪,它停止跟踪用这个装饰器装饰的函数的范围。 通常,对被跟踪方法的调用可以分为两类:由新接口实现进行的调用,以及不是由新接口实现调用的调用。 我们已经知道和期望的调用——即来自新实现的那些调用——可以被忽略,因为我们只对捕获我们不知道的调用感兴趣。 因此,我们使用这个 @不跟踪 装饰器隐藏该实现进行的任何跟踪调用。 此时,唯一被跟踪的调用将是来自新实现之外的调用。

通过这种方式,对数据库进行预期和已知的调用(例如,通过接口 XBlock用户状态客户端) 没有记录,让我们清楚地了解未知呼叫在做什么。 此外,调用堆栈中的重复帧已使用正则表达式过滤器进行过滤。 通过这种方式,记录的通话数量更少、更精确、更易于阅读。

上面提到的调用堆栈的示例如下 -

记录新的调用堆栈号 4:
   文件“/edx/app/edxapp/edx-platform/lms/djangoapps/instructor/views/api.py”,第 240 行,已包装
    返回函数(*args,**kwargs)
  文件“/edx/app/edxapp/edx-platform/lms/djangoapps/instructor/views/api.py”,第 176 行,已包装
    返回函数(*args,**kwargs)
  文件“/edx/app/edxapp/edx-platform/lms/djangoapps/instructor/views/api.py”,第 127 行,已包装
    返回函数(请求,*args,**kwargs)
  文件“/edx/app/edxapp/edx-platform/lms/djangoapps/instructor/views/api.py”,第 1896 行,在 rescore_problem
    coach_task.api.submit_rescore_problem_for_student(请求,module_state_key,学生)
  文件“/edx/app/edxapp/edx-platform/lms/djangoapps/instructor_task/api.py”,第 110 行,在 submit_rescore_problem_for_student
    返回 submit_task(请求,task_type,task_class,usage_key.course_key,task_input,task_key)
  submit_task 中的文件“/edx/app/edxapp/edx-platform/lms/djangoapps/instructor_task/api_helper.py”,第 346 行
    task_class.apply_async(task_args,task_id=task_id)
  文件“/edx/app/edxapp/edx-platform/lms/djangoapps/instructor_task/tasks.py”,第 80 行,在 rescore_problem
    返回 run_main_task(entry_id, visit_fcn, action_name)
  文件“/edx/app/edxapp/edx-platform/lms/djangoapps/instructor_task/tasks_helper.py”,第 279 行,在 run_main_task
    task_progress = task_fcn(entry_id, course_id, task_input, action_name)
  文件”/edx/app/edxapp/edx-platform/lms/djangoapps/instructor_task/tasks_helper.py”,第 345 行,在 perform_module_state_update
    module_to_update = StudentModule.objects.filter(course_id=course_id, module_state_key__in=usage_keys)

在开发调用堆栈管理器库期间,我必须解决许多基本的 Python 级别问题,例如有效处理 Django 模型类、在运行时创建 Django 模型类以进行测试、包装函数以使它们不会丢失其身份,处理与其他装饰器的冲突,例如 @合同 在 PyContracts 中,等等。

调用堆栈管理器作为通用库

调用堆栈管理器的主要目的是跟踪调用 学生模块 以及 学生模块历史. 此外,我们可以在任何特定代码级别跟踪任何 Python 函数。 可以在需要时停止跟踪。 通过使用这个库,我们可以通过跟踪未知调用来有效地弃用不需要的函数。 将这个工具开发为适用于任何 Django 项目的通用工具将会很有趣。

结语

我坚信调用堆栈管理器的通用解决方案可以用作 Django/Python 项目的插件或标准库,并进行进一步的添加和修改。

回顾我的实习经历,我喜欢在 edX 代码库上工作。 从事这样一个具有巨大全球影响力的大型开源项目是非常令人兴奋的。 EdX 拥有一支出色的编码人员团队,并将实习生视为全职员工,在各个层面都有最大的曝光率。 我发现自己致力于尖端技术,并参与了与平台团队的各种技术讨论。 在基本的 Python 水平上工作并解决不寻常和意想不到的问题尤其有益。 我要感谢 John Eskew、Calen Pennington、Ali Mohammad、Brian Beggs、Miki Goyal、Adam Palay 和 Ned Batchelder 的持续帮助和支持。 在 edX 工作是一个令人着迷且充满挑战的机会,我将在未来数年珍惜。

装载

时间更多? 查看下面的文章。

企业学习进军教育科技
征文大丰收
打开 edX 论文征集:7 月 XNUMX 日结束
Open edX 的增量改进
参加 2026 年 Open edX 会议!

2026 年 Open edX 会议将展示世界上最好的开源在线学习管理系统之一 Open edX 平台的创新用例,并发现教学设计、课程群以及操作和扩展 Open edX 平台的方法方面的最新进展,包括突破性技术,例如生成式人工智能。