Skip to content

Commit

Permalink
docs: [FC-0074] - Style corrections for references and concepts
Browse files Browse the repository at this point in the history
This PR modifies some elements of the references and concepts' documents for the events repository, like the titles' RST codes and minor grammar corrections.
  • Loading branch information
Apgomeznext committed Feb 4, 2025
1 parent bd05801 commit 328945f
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 43 deletions.
32 changes: 16 additions & 16 deletions docs/concepts/event-bus.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,35 @@ The :term:`Event Bus` can help us achieve loose coupling between services, repla

* **Eliminate Blocking, Synchronous Requests**: reduce site outages when services become overloaded with requests by replacing synchronous calls with asynchronous communication.
* **Eliminate Expensive, Delayed, Batch Synchronization**: replace expensive batch processing with near real-time data updates.
* **Reduce the need for Plugins**: reduce the computational load for plugins that don't need to run in the same process by allowing cross-service communication of lifecycle events.
* **Reduce the Need for Plugins**: reduce the computational load for plugins that don't need to run in the same process by allowing cross-service communication of lifecycle events.

How Does the Open edX Event Bus Work?
***************************************

The Open edX platform uses the ``OpenEdxPublicSignals`` (Open edX-specific Django Signals) to send events within a service. The event bus extends these signals, allowing them to be broadcasted and handled across multiple services. That's how Open edX Events are used for internal and external communication. For more details on how these Open edX-specific Django Signals are used by the event bus, refer to the :doc:`../decisions/0004-external-event-bus-and-django-signal-events` Architectural Decision Record (ADR).

Open edX Events provides an abstract implementation of the `publish/subscribe messaging pattern`_ (pub/sub) which is the chosen pattern for the event bus implementation as explained in :doc:`openedx-proposals:architectural-decisions/oep-0052-arch-event-bus-architecture`. It implements two abstract classes, `EventProducer`_ and `EventConsumer`_ which allow concrete implementations of the event bus based on different message brokers, such as Pulsar.
Open edX Events provides an abstract implementation of the `publish/subscribe messaging pattern`_ (pub/sub), which is the chosen pattern for the event bus implementation, as explained in :doc:`openedx-proposals:architectural-decisions/oep-0052-arch-event-bus-architecture`. It implements two abstract classes, `EventProducer`_ and `EventConsumer`_, which allow concrete implementations of the event bus based on different message brokers, such as Pulsar.

This abstraction allows for developers to implement their own concrete implementations of the event bus in their own plugins. There are currently two implementations of the event bus, Redis (`event-bus-redis`_) and Kafka (`event-bus-kafka`_). Redis streams is a data structure that acts like an append-only log, and Kafka is a distributed event streaming application. Both implementations handle event production and consumption with technology specific methods.
This abstraction allows for developers to implement their own concrete implementations of the event bus in their own plugins. There are currently two implementations of the event bus, Redis (`event-bus-redis`_) and Kafka (`event-bus-kafka`_). Redis streams is a data structure that acts like an append-only log, and Kafka is a distributed event streaming application. Both implementations handle event production and consumption using technology-specific methods..

Architectural Diagram
*********************

These diagrams show what happens when an event is sent to the event bus. The event-sending workflow follows the same steps as explained in the :ref:`events architecture`, with a key difference: when configured, the event bus recognizes events and publishes them to the message broker for consumption by other services.
These diagrams show what happens when an event is sent to the event bus. The event-sending workflow follows the same steps as explained in the :ref:`events-architecture`, with a key difference: when configured, the event bus recognizes events and publishes them to the message broker for consumption by other services.

Components
==========
=============

* **Service A (Producer)**: The service that emits the event. Developers may have emitted this event in a key section of the application logic, signaling that a specific action has occurred.
* **Service B (Consumer)**: The service that listens for the event and executes custom logic in response.
* **OpenEdxPublicSignal**: The class that implements all methods used to manage sending the event. This class inherits from Django's Signals class and adds Open edX-specific metadata and behaviors.
* **Event Producer**: The class in the :term:`Producer` service that sends events to the event bus. The producer serializes the event data and enriches it with relevant metadata for the consumer.
* **Event Consumer**: The class in the :term:`Consumer` service that receives events from the event bus. The consumer deserializes the :term:`message <Message>` and re-emits it as an event with the data that was transmitted.
* **Message Broker**: The :term:`message broker <Message Broker>` is responsible for storing and delivering messages between the producer and consumer.
* **Event Bus Plugin**: The concrete implementation of the event bus (EventProducer and EventConsumer) based on a specific :term:`message broker <Message Broker>`, such as Pulsar. The plugin handles event production and consumption with technology-specific methods.
* **Event Bus Plugin**: The concrete implementation of the event bus (EventProducer and EventConsumer) based on a specific :term:`message broker <Message Broker>`, such as Pulsar. The plugin handles event production and consumption using technology-specific methods.

Workflow
=========
==========

.. image:: ../_images/event-bus-workflow-service-a.png
:alt: Open edX Event Bus Workflow (Service A)
Expand All @@ -61,8 +61,8 @@ From Service A (Producer)

1. When the event is sent, a registered event receiver `general_signal_handler`_ is called to send the event to the event bus. This receiver is registered by the Django Signal mechanism when the ``openedx-events`` app is installed, and it listens for all Open edX Events.
2. The receiver checks the ``EVENT_BUS_PRODUCER_CONFIG`` to look for the ``event_type`` of the event that was sent.
3. If the event type is found and it's enabled for publishing in the configuration, the receiver obtains the configured producer class (``EventProducer``) from the concrete event bus implementation. For example, the producer class for Redis or Kafka implemented in their respective plugins.
4. The ``EventProducer`` serializes the event data and enriches it with relevant metadata, and then transforms it into a message that can be transmitted.
3. If the event type is found and it's enabled for publishing in the configuration, the receiver obtains the configured producer class (``EventProducer``) from the concrete event bus implementation. For example, the producer class for Redis or Kafka is implemented in their respective plugins.
4. The ``EventProducer`` serializes the event data, enriches it with relevant metadata, and then transforms it into a message that can be transmitted.
5. The producer uses its technology-specific ``send`` method to publish a message to the configured broker (e.g., Redis or Kafka).

.. image:: ../_images/event-bus-workflow-service-b.png
Expand All @@ -76,20 +76,20 @@ From Service B (Consumer)
2. When a new message is found, the ``EventConsumer`` deserializes the message and re-emits it as an event with the data that was transmitted.
3. The event sending and processing workflow repeats in Service B.

This approach of producing events via settings with the generic handler was chosen to allow for flexibility in the event bus implementation. It allows developers to choose the event bus implementation that best fits their needs, and to easily switch between implementations if necessary. See more details in the :doc:`../decisions/0012-producing-to-event-bus-via-settings` Architectural Decision Record (ADR).
This approach of producing events via settings with the generic handler was chosen to allow for flexibility in the event bus implementation. It allows developers to choose the event bus implementation that best fits their needs, and easily switch between implementations if necessary. See more details in the :doc:`../decisions/0012-producing-to-event-bus-via-settings` Architectural Decision Record (ADR).

Event Bus vs Asynchronous Tasks
********************************

Asynchronous tasks are used for long-running, resource-intensive operations that should not block the main thread of a service. The event bus is used for broadcasting messages to multiple services, allowing them to react to changes or actions in the system. Both can be used for asynchronous communication, but they serve different purposes and have different workflows.
Asynchronous tasks are used for long-running, resource-intensive operations that should not block the main thread of a service. The event bus broadcasts messages to multiple services, allowing them to react to changes or actions in the system. Both can be used for asynchronous communication, but they serve different purposes and have different workflows.

In this diagram, you can see the difference between the two when it comes to asynchronous communication:

.. image:: ../_images/event-bus-vs-asynchronous-tasks.png
:alt: Open edX Event Bus vs Asynchronous Tasks
:align: center

In the upper part of the diagram, we have Service A and Service B. Service A is the producer of the event, and a :term:`Worker` of Service B is the consumer. This is the event bus workflow which allows asynchronous non-blocking communication between services:
In the upper part of the diagram, we have Service A and Service B. Service A is the producer of the event, and a :term:`Worker` of Service B is the consumer. This is the event bus workflow, which allows asynchronous, non-blocking communication between services:

- Service A sends the event as a message to the event bus and continues its execution, as we previously explained.
- Service B polls the message broker for new messages and converts them into ``OpenEdxPublicSignal``.
Expand All @@ -105,23 +105,23 @@ In the lower part of the diagram, we have the asynchronous tasks workflow:

If we were to introduce a Service C in this scenario, it would need to wait for the worker of Service A to finish processing the response from Service B and receive a response before it could continue.

This is an example of an asynchronous approach (from the producer point of view) to send messages to another services but with a blocking nature.
This is an example of an asynchronous approach (from the producer's point of view) to send messages to other services but with a blocking nature.

Use the Open edX Event bus instead of asynchronous tasks when:

- You want to send a message but don't need a response. For example, notifying other services of an event that occurred.
- You need to send a high volume of messages to a single or multiple services. For example, notifying when users visit a unit in a course or watch a video.
- You need to send a high volume of messages to a single or multiple services. For example, notifying when the users visit a unit in a course or watch a video.
- You want to decouple services and avoid direct dependencies.
- You want to send events out of the Open edX ecosystem. For example, external databases or services that can consume events to update their own state.

When you need to send a message to a particular service and wait their response for further processing, use asynchronous tasks.
Use asynchronous tasks when you need to send a message to a particular service and wait for their response for further processing.

How is the Open edX Event Bus Used?
************************************

The event bus is used to broadcast Open edX Events to multiple services, allowing them to react to changes or actions in the system.

We encourage you to review the :doc:`../reference/real-life-use-cases` page for examples of how the event bus is used in the Open edX ecosystem by the community. Also, see the :doc:`../how-tos/use-the-event-bus-to-broadcast-and-consume-events` guide to get start sending events to the event bus.
We encourage you to review the :doc:`../reference/real-life-use-cases` page for examples of how the community uses the event bus in the Open edX ecosystem. Also, see the :doc:`../how-tos/use-the-event-bus-to-broadcast-and-consume-events` guide to start sending events to the event bus.

.. _general_signal_handler: https://github.com/openedx/openedx-events/blob/main/openedx_events/apps.py#L16-L44
.. _EventProducer: https://github.com/openedx/openedx-events/blob/main/openedx_events/event_bus/__init__.py#L71-L91
Expand Down
17 changes: 8 additions & 9 deletions docs/concepts/openedx-events.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Open edX Events
#################

Overview
**********
*********

Open edX Events provide a mechanism for extending the platform by enabling developers to listen to Open edX-specific Django signals emitted by various services and respond accordingly. This allows for customized reactions to actions or changes within the platform without modifying the Open edX platform codebase, with the main goal of minimizing maintenance efforts for the Open edX project and plugin maintainers.

Expand All @@ -13,12 +13,11 @@ Open edX Events are signals emitted by a service (e.g., LMS, CMS, or others) wit

These events are built on top of Django signals, inheriting their behavior while also incorporating metadata and actions specific to the Open edX ecosystem, making them uniquely suited for Open edX. Since they are essentially Django signals tailored to Open edX's specific needs, we can refer to `Django Signals Documentation`_ for a more detailed understanding of Open edX Events.

.. note:: Django includes a "signal dispatcher", which helps decoupled applications be notified when actions occur elsewhere in the framework. In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place. They're especially useful when many pieces of code may be interested in the same events.

.. note:: Django includes a "signal dispatcher" which helps decoupled applications be notified when actions occur elsewhere in the framework. In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place. They're especially useful when many pieces of code may be interested in the same events.

Events are primarily used as a communication method between internal services by leveraging Django Signals and external services using the :doc:`../concepts/event-bus`, making them the standard communication mechanism within the Open edX ecosystem.

How Do Open edX Events Work?
How do Open edX Events work?
****************************

Open edX Events are implemented by a class called `OpenEdxPublicSignal`_, which inherits from `Django's Signals class` and adds behaviors specific to the Open edX ecosystem. Thanks to this design, ``OpenEdxPublicSignal`` leverages the functionality of Django signals, allowing developers to apply their existing knowledge of the Django framework. You can review the :doc:`Open edX Events Tooling <../reference/events-tooling>` documentation for more information on the tooling available for working with Open edX events.
Expand All @@ -35,19 +34,19 @@ In this diagram, we illustrate the workflow of emitting and processing an Open e
:align: center

Components
==========
===========

* **Application (caller):** The application component that emits the event. Developers may have emitted this event in a key section of the application logic, signaling that a specific action has occurred. E.g., a user has enrolled in a course, `triggering the COURSE_ENROLLMENT_CREATED event`_.
* **OpenEdxPublicSignal:** The class that implements all methods used to manage sending the event. As mentioned previously, this class inherits from Django's Signals class and adds Open edX-specific metadata and behaviors.
* **Django Signals:** The Django framework's built-in signal mechanism.
* **Receiver1...ReceiverN:** The components that listen to the event and execute custom logic in response. This receivers are implemented as Django signal receivers.
* **Receiver1...ReceiverN:** The components that listen to the event and execute custom logic in response. These receivers are implemented as Django signal receivers.

Workflow
=========

#. An application (caller) emits an event by calling the `send_event`_ method implemented by `OpenEdxPublicSignal`_ which the event inherits from.

#. The caller passes the :term:`event payload<Event Payload>` to the `send_event`_ method. The event payload is the data associated with the event that is passed to the receivers when it's triggered, and uses data attribute classes (e.g. ``CourseEnrollmentData``, ``UserData``, etc.) to carry data about the event.
#. The caller passes the :term:`event payload<Event Payload>` to the `send_event`_ method. The event payload is the data associated with the event that is passed to the receivers when it's triggered. It uses data attribute classes (e.g. ``CourseEnrollmentData``, ``UserData``, etc.) to carry data about the event.

#. The `send_event`_ method generates Open edX-specific metadata for the event on the fly, like the event version or the timestamp when the event was sent. The event receivers can access this metadata during their processing.

Expand All @@ -72,8 +71,8 @@ Here is an example of an event that saves a user's notification preferences when

The `Django Signals Documentation`_ provides a more detailed explanation of how Django signals work.

How are Open edX Events used?
******************************
How Are Open edX Events Used?
*****************************

As mentioned previously, developers can listen to Open edX Events by registering signal receivers from their Open edX Django plugins that respond to the emitted events or by using the :doc:`../concepts/event-bus` to send events to external services.

Expand Down
8 changes: 4 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
contain the root `toctree` directive.
Welcome to Open edX Events' Documentation!
############################################
###########################################

Open edX Events is a type of hook in the Hooks Extension Framework that allows extending the Open edX platform in a more stable and maintainable way. If you are new to this approach for extending Open edX, start by reading the :doc:`docs.openedx.org:developers/concepts/hooks_extension_framework` documentation. This documentation provides an overview of the framework's concepts and structure, which are useful to support your adoption of Open edX Events.
Open edX Events is a type of hook in the :doc:`Hooks Extension Framework<docs.openedx.org:developers/concepts/hooks_extension_framework` documentation>` that allows extending the Open edX platform in a more stable and maintainable way. If you are new to this approach for extending Open edX, start by reading the :doc:`docs.openedx.org:developers/concepts/hooks_extension_framework` documentation. This documentation provides an overview of the framework's concepts and structure, which are useful to support your adoption of Open edX Events.

This repository contains all the references, concepts, how-tos, quickstarts and Architectural Decision Records (ADRs) related to the Open edX Events necessary to implement this hook in your instance.

Expand All @@ -15,7 +15,7 @@ This repository contains all the references, concepts, how-tos, quickstarts and
:caption: Contents:

concepts/index
decisions/index
reference/index
how-tos/index
quickstarts/index
reference/index
decisions/index
2 changes: 1 addition & 1 deletion docs/reference/event-bus-configurations.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Event Bus Configuration
=======================
########################

Here are the available configurations for the event bus that are used to setup the event bus in the Open edX platform.

Expand Down
Loading

0 comments on commit 328945f

Please sign in to comment.