Praktikanten-Spotlight: Utkarsh Jadhav

9. September 2015 | Von

Mein Name ist Utkarsh Jadhav und ich bin ein Master-Student der Informatik an der Northeastern University hier in Boston. Ich habe die letzten dreizehn Wochen bei edX verbracht und mit dem Plattform-Team zusammengearbeitet. Das Plattform-Team ist für den Aufbau der Infrastruktur für Open edX-Produkte verantwortlich und arbeitet insbesondere daran, den Code schneller laufen zu lassen. In diesem Beitrag möchte ich eines meiner Hauptprojekte hervorheben, den Call Stack Manager. Es ist ein Tool, das eindeutige Call-Stacks von Funktionen, Methoden und Django-Modellklassen verfolgt.

Kursunterlagen Studentenmodul (CSM) undCourseware Studentisches Modul Geschichte (CSMH) im edx-Plattformcode sind dafür verantwortlich, den Benutzerstatus von Schülern, die Probleme versuchen, und ihre jeweiligen Noten aufrechtzuerhalten. Die Website edx.org erreichte kürzlich 5 Millionen Lernende; Die wachsende Größe von CSM und CSMH verursacht ernsthafte Bedenken hinsichtlich Platz- und Datenbankausfällen. Das Aufbrechen monolithischer Codebereiche wie LMS und CMS in der edx-Plattform ist eine wesentliche Notwendigkeit, da die Codebasis und das Datenbankvolumen zunehmen.

edX-Benutzerstatus-Client (eUSC)

Ursprünglich war die Struktur des Benutzerstatus-Clients wie folgt:

Vorherige Struktur des User State Client, die die Kommunikation zwischen der edx-Plattform und der MySQL-Datenbank über CSM/CSMH zeigt

Vorherige Struktur des User State Client, die die Kommunikation zwischen der edx-Plattform und der MySQL-Datenbank über CSM/CSMH zeigt

Die ganze Struktur war unter edx/edx-Plattform. Der Benutzerstatus-Client kommunizierte direkt mit den genannten MySQL-Tabellen courseware_studentmodule und courseware_studentmodulehistoryüber das DjangoORM.

Als ich mein Praktikum anfing, wusste das Team bereits um die Schattenseiten dieser Architektur. Um dies zu beheben, half ich bei der Implementierung der vorgeschlagenen Architektur, die in der folgenden Abbildung dargestellt ist:

Vorgeschlagene Struktur des User State Client, die eine Schicht edx-user-state-client zwischen der Plattform und dem Datenbank-Backend zeigt

Vorgeschlagene Struktur des User State Client, die eine Schicht edx-user-state-client zwischen der Plattform und dem Datenbank-Backend zeigt

In dieser neuen Architektur edx-user-state-client fungiert als Schicht zwischen der edx-Plattform und den Datenbank-Backends. Die Verwendung einer solchen Struktur hat viele Vorteile:

  1. eUSC fungiert als einzelne Schnittstelle auf einer abstrahierten Ebene, über die alle Datenbankaufrufe erfolgen. Ein solches Muster wird schließlich bei der effektiven Kommunikation mit der Datenbank helfen.
  2. eUSC wird auch einen einfachen Wechsel zwischen verschiedenen Backends ermöglichen. Diese API ermöglicht eine Auswahl für Backends, sogar für verteilte Aufgaben.

Als ersten Schritt zum Erstellen dieser Struktur habe ich ein Repository mit dem Namen erstellt edx/edx-user-state-client. Dieses Repository enthält die Schnittstelle XBlockUserStateClient, das sich um alle Aufrufe kümmert, die von Django-Modellklassen mit der Datenbank getätigt werden.

Call-Stack-Manager

Die XBlockUserStateClient ist für alle Aufrufe der Datenbank verantwortlich. In Anbetracht der immensen Größe der edX-Codebasis, der Verwendung von Erweiterungen von Drittanbietern (z. B. XBlocks) und vieler Datenbankaufrufe an verschiedenen Stellen lohnt es sich jedoch, Aufrufe an die Datenbank abzufangen, die nicht über die Schnittstelle erfolgen XBlockUserStateClient.

Um diesem Bedarf gerecht zu werden, habe ich eine Bibliothek namens entwickelt Call-Stack-Manager. Dies ist eine Bibliothek, die es uns ermöglicht, Anrufe zu verfolgen, die nicht über die Schnittstelle getätigt werden und direkt mit der Datenbank kommunizieren. Call Stack Manager protokolliert solche Aufrufe im LMS-Protokoll.

Die Bibliothek implementiert zwei Hauptdekorateure:

  1. @verfolge es – die die dekorierte Entität verfolgt
  2. @nicht verfolgen – was die Verfolgung von dekorierten Entitäten stoppt @verfolge es.

Die primäre Notwendigkeit, diese Bibliothek zu entwickeln, bestand hauptsächlich darin, Aufrufe von Model-Klassen in CSM und CSMH zu verfolgen StudentModul und StudentModulGeschichte. Die Kommunikation mit Datenbanken in Django erfolgt durch benutzerdefinierte Klassen, die Unterklassen der Django 'Model'-Klasse. Modellklassen verwenden die QuerySet-API zum Erstellen, Abrufen und Aktualisieren von Datenbanken. Aufrufe der QuerySet-API können mit einem benutzerdefinierten Manager namens überschrieben werden CallStackManager – definiert in der Bibliothek Call Stack Manager. Auf diese Weise wurde der spezielle Fall des Verfolgens von Django-Modellklassen behandelt, die direkt auf die Datenbank zugreifen.

Beim Ausführen von Call Stack Manager in seiner ursprünglichen Version hatte ich folgende Probleme:

  1. Anrufprotokolle wurden wiederholt erstellt, wodurch das LMS-Protokoll unübersichtlich wurde.
  2. Viele Anrufe, von denen wir bereits wussten, wurden unnötig aufgezeichnet.
  3. Anrufprotokolle enthielten unnötige Frames, was das Lesen lang und schwer machte.

Um diese Probleme anzugehen, habe ich einen neuen Dekorateur namens @nicht verfolgen, wodurch die Nachverfolgung für den Bereich der mit diesem Dekorateur dekorierten Funktion angehalten wird. Im Allgemeinen können Aufrufe an eine nachverfolgte Methode in zwei Kategorien eingeteilt werden: Aufrufe, die von der neuen Schnittstellenimplementierung vorgenommen werden, und Aufrufe, die dies nicht tun. Aufrufe, die wir bereits kennen und erwarten – also Aufrufe aus der neuen Implementierung – können ignoriert werden, da wir nur daran interessiert sind, Aufrufe zu erfassen, von denen wir nichts wissen. Daher nutzen wir diese @nicht verfolgen decorator, um alle nachverfolgten Aufrufe dieser Implementierung zu verbergen. Zu diesem Zeitpunkt werden nur die Anrufe verfolgt, die von außerhalb der neuen Implementierung getätigt werden.

Auf diese Weise werden erwartete und bekannte Aufrufe an die Datenbank (z. B. über die Schnittstelle XBlockUserStateClient) wurden nicht protokolliert, was uns ein klares Bild davon gibt, was unbekannte Anrufe taten. Außerdem wurden doppelte Frames in der Aufrufliste mithilfe von Filtern mit regulären Ausdrücken gefiltert. Auf diese Weise war die Anzahl der aufgezeichneten Anrufe geringer, präziser und besser ablesbar.

Ein Beispiel für einen oben erwähnten Aufrufstapel ist wie folgt:

Neue Aufrufliste Nr. 4 protokollieren für:
   Datei „/edx/app/edxapp/edx-platform/lms/djangoapps/instructor/views/api.py“, Zeile 240, umschlossen
    return func(*args, **kwargs)
  Datei „/edx/app/edxapp/edx-platform/lms/djangoapps/instructor/views/api.py“, Zeile 176, umschlossen
    return func(*args, **kwargs)
  Datei „/edx/app/edxapp/edx-platform/lms/djangoapps/instructor/views/api.py“, Zeile 127, umschlossen
    return func(request, *args, **kwargs)
  Datei „/edx/app/edxapp/edx-platform/lms/djangoapps/instructor/views/api.py“, Zeile 1896, in rescore_problem
    Instructor_task.api.submit_rescore_problem_for_student(request, module_state_key, student)
  Datei „/edx/app/edxapp/edx-platform/lms/djangoapps/instructor_task/api.py“, Zeile 110, in submit_rescore_problem_for_student
    returnsubmit_task(request, task_type, task_class,use_key.course_key, task_input, task_key)
  Datei „/edx/app/edxapp/edx-platform/lms/djangoapps/instructor_task/api_helper.py“, Zeile 346, in submit_task
    task_class.apply_async(task_args, task_id=task_id)
  Datei „/edx/app/edxapp/edx-platform/lms/djangoapps/instructor_task/tasks.py“, Zeile 80, in rescore_problem
    return run_main_task(entry_id, visit_fcn, action_name)
  Datei „/edx/app/edxapp/edx-platform/lms/djangoapps/instructor_task/tasks_helper.py“, Zeile 279, in run_main_task
    task_progress = task_fcn(entry_id, course_id, task_input, action_name)
  Datei „/edx/app/edxapp/edx-platform/lms/djangoapps/instructor_task/tasks_helper.py“, Zeile 345, in perform_module_state_update
    module_to_update = StudentModule.objects.filter(course_id=course_id, module_state_key__in=usage_keys)

Während der Entwicklung der Call Stack Manager-Bibliothek musste ich zahlreiche grundlegende Probleme auf Python-Ebene lösen, wie z , Umgang mit Konflikten mit anderen Dekorateuren wie z @Vertrag in PyContracts und viele mehr.

Call Stack Manager als allgemeine Bibliothek

Der Hauptzweck des Call Stack Managers bestand darin, Anrufe von zu verfolgen StudentModul und StudentModulGeschichte. Darüber hinaus können wir jede Python-Funktion auf jeder bestimmten Codeebene verfolgen. Die Verfolgung kann bei Bedarf angehalten werden. Mit der Verwendung dieser Bibliothek können wir unerwünschte Funktionen effektiv verwerfen, indem wir unbekannte Aufrufe verfolgen. Es wird interessant sein, dieses Tool als generisches Tool weiterzuentwickeln, das auf jedes Django-Projekt anwendbar ist.

Fazit

Ich bin fest davon überzeugt, dass die verallgemeinerte Lösung des Call Stack Managers mit weiteren Ergänzungen und Modifikationen als Plugin oder Standardbibliothek für Django/Python-Projekte verwendet werden kann.

Wenn ich auf meine Praktikumserfahrung zurückblicke, hat mir die Arbeit an der edX-Codebasis Spaß gemacht. Die Arbeit an einem so großen Open-Source-Projekt mit enormer globaler Wirkung ist sehr aufregend. EdX hat ein Team von großartigen Programmierern und behandelt Praktikanten als Vollzeitangestellte mit maximaler Exposition auf allen Ebenen. Ich arbeitete an Spitzentechnologien und nahm an allen Arten von technischen Diskussionen mit dem Plattform-Team teil. Besonders lohnend war es, auf der grundlegenden Python-Ebene zu arbeiten und ungewöhnliche und unerwartete Probleme zu lösen. Ich möchte John Eskew, Calen Pennington, Ali Mohammad, Brian Beggs, Miki Goyal, Adam Palay und Ned Batchelder für ihre fortwährende Hilfe und Unterstützung danken. Die Arbeit bei edX war eine faszinierende und herausfordernde Gelegenheit, die ich in den kommenden Jahren schätzen werde.

Laden

Zeit für mehr? Sehen Sie sich die folgenden Artikel an.

Corporate Learning hält Einzug in die Ed Tech
Call for Papers liefert eine Rekordernte
Open edX Call for Papers: Endet am 7. Dezember
Inkrementelle Verbesserungen an Open edX
Nehmen Sie an der Open edX Conference 2026 teil!

Auf der Open edX-Konferenz 2026 werden innovative Anwendungsfälle für eines der weltweit besten Open-Source-Online-Lernmanagementsysteme, die Open edX-Plattform, vorgestellt und die neuesten Fortschritte im Lehrdesign, der Kurskonstellation und Methoden für den Betrieb und die Erweiterung der Open edX-Plattform vorgestellt , einschließlich bahnbrechender Technologien wie generativer KI.