Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: [FC-0074] add ADR with event design suggestions #438

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

mariajgrimaldi
Copy link
Member

@mariajgrimaldi mariajgrimaldi commented Dec 17, 2024

Description

This PR adds an ADR with suggestions on how to design a new event based on the Building Event-Driven Microservices 3rd chapter about Communication and Data Contracts and Martin Fowler's Event Driven article. I'm proposing that these practices be considered when implementing new events, but they should NOT be considered standards that all events should strictly follow. Also, I'm not saying either that all the existing events in the library comply (or should) with these practices.

This document will be used as a reference in the How to Create a New Event guide. I'm currently validating these items while I write the guide, making sure these suggestions are clear enough to follow. You can review it here: #439

Testing instructions

Review here: https://docsopenedxorg--438.org.readthedocs.build/projects/openedx-events/en/438/decisions/0016-event-design-practices.html

Deadline

None

Checklists

Check off if complete or not applicable:

Merge Checklist:

  • All reviewers approved
  • Reviewer tested the code following the testing instructions
  • CI build is green
  • Version bumped
  • Changelog record added with short description of the change and current date
  • Documentation updated (not only docstrings)
  • Code dependencies reviewed
  • Fixup commits are squashed away
  • Unit tests added/updated
  • Noted any: Concerns, dependencies, migration issues, deadlines, tickets

Post Merge:

  • Create a tag
  • Create a release on GitHub
  • Check new version is pushed to PyPI after tag-triggered build is
    finished.
  • Delete working branch (if not needed anymore)
  • Upgrade the package in the Open edX platform requirements (if applicable)

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Dec 17, 2024
@openedx-webhooks
Copy link

openedx-webhooks commented Dec 17, 2024

Thanks for the pull request, @mariajgrimaldi!

This repository is currently maintained by @openedx/hooks-extension-framework.

Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.

🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads

🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.


Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@mariajgrimaldi
Copy link
Member Author

@robrap @bmtcril I'd like to know what you folks think about this proposal based on your experience working with this architecture.

@mariajgrimaldi mariajgrimaldi marked this pull request as ready for review December 18, 2024 11:04
@mariajgrimaldi mariajgrimaldi requested a review from a team as a code owner December 18, 2024 11:04
@mariajgrimaldi mariajgrimaldi changed the title docs: add ADR with event design suggestions based on industry standards docs: [FC-0074] add ADR with event design suggestions based on industry standards Dec 18, 2024
@mariajgrimaldi mariajgrimaldi added the FC Relates to an Axim Funded Contribution project label Dec 18, 2024
@mariajgrimaldi
Copy link
Member Author

mariajgrimaldi commented Dec 18, 2024

FYI @Squirrel18 @Alec4r

@mariajgrimaldi mariajgrimaldi changed the title docs: [FC-0074] add ADR with event design suggestions based on industry standards docs: [FC-0074] add ADR with event design suggestions Dec 18, 2024
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- Design events with a single responsibility in mind. Each event should represent a single action or fact that happened in the system. If an event contains multiple actions, consider splitting it into multiple events. For instance, if the course grade is updated to pass or fail, there should be two events: one for the pass action and another for the fail action.
- Manage the granularity of the event so it is not too coarse (generic with too much information) or too fine-grained (specific with too little information). When making a decision on the granularity of the event, start with the minimum required information for consumers to react to the event and add more information as needed with enough justification. If necessary, leverage API calls from the consumer side to retrieve additional information but always consider the trade-offs of adding dependencies with other services.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the idea of avoid generic events, however, we should also avoid split events like course_passed or course_failed when we could use just course_completed with an status.

could we include a practical example on an appropiate level of granularity?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm interested in understanding why having a status is better. I think that in this case, it'd be easier to consume more granular events than leave the responsibility to the consumer to figure out whether the student passed or failed based on the status.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your perspective, and I think both approaches have valid use cases depending on the context, let me elaborate on why I suggested using course_completed with a status field and we can discuss further to find a balance

If the event represents a single conceptual action for example: completing a course, having one event like course_completed with a clear status passed, failed, etc. could simplify the producer's logic and reduce event proliferation and for consumers, interpreting the status field is relatively straightforward if it's well-documented and includes only a few well-defined values, however if different consumers need to handle passed and failed cases in significantly different ways, separate those events might reduce complexity for them but emitting separate events like course_passed and course_failed could also create challenges such as needing to ensure mutual exclusivty.

So in cases like this I think We could start with course_completed and a status field, ensuring it is well-documented and strictly validted and if in the future we observe a clear need for distinct event flows We could introduce the more granular events without breaking existing consumers.

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Dec 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the example we're using, I still think it'd be more straightforward to send smaller and more specific events. As I see it, course completion and grade passing would be two different critical facts happening in the system; therefore, they should be independent. This is more of a question of what consumers would want with a course completion event or a course passing status change.

In any case, these are the only suggestions that should be evaluated for each case. We currently have an event called COURSE_PASSING_STATUS_UPDATED which uses a similar flow control status field called is_passing. In that case, given that the status is directly related to the event, using a status field is acceptable. What do you think? Should we maybe use a rule of thumb indicating that an event can be split into more events, given that they could communicate more facts of the system?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Alec4r I worry that your example is predicated on understanding the needs of the consumers. I don't think that's always possible, to predict how various consumers will need to consume events. I agree with @mariajgrimaldi that consuming an event that doesn't require me to also check the status field is conceptually simpler, even if it means I need to handle consuming a few discrete events.

~~~~~~~~~~~~~~~~~~~~~~~

- When designing an event, consider the consumers that will be using it. What information do they need to react to the event? What data is necessary for them to process the event?
- Design events carefully from the start to minimize breaking changes for consumers, although it is not always possible to avoid breaking changes.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will it be necessary to version events to handle event changes, or what is the plan for handling event changes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Events are versioned by definition, see this ADR for more info. As for the evolution of the events schema, this other ADR describes what the behavior is supposed to be: https://github.com/openedx/openedx-events/blob/main/docs/decisions/0006-event-schema-serialization-and-evolution.rst#decision, although according to this comment the ADR might be outdated -- I'll be working on updating it. The reality is that we haven't needed to change an event definition in any way that's breaking.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@robrap: Can you help us figure out what needs to change from the ADR-0006? I could do it, but I need more context to do it effectively.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @mariajgrimaldi. I was off for the last two weeks, so just getting back to things.

It seems like you are pretty up to date. I'll summarize what I think you are already saying.

  1. As noted in the comment you linked to, the existence of optional fields probably changes the 0006 recommendation. The first sentence of the deferred alternatives in the ADR reads: "We could add the ability to add optional fields to an event...". And we did add this ability.
  2. Most importantly, no events have actually gone through any process of evolution, so all of this is just best-guesses about what we'd like to do and how we think it would work. It was deemed too much effort to proceed any further without an actual need.

Does this help? Let me know if you have any specific questions.

Copy link
Member Author

@mariajgrimaldi mariajgrimaldi Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it helps! Thank you. So I'll go ahead and create a new ADR considering the full transitive evolution strategy, so at least it is documented somewhere, noting that we haven't gone through any process of evolution just yet.

I'll update the ADR in the coming weeks as a different effort. Thank you!

@mariajgrimaldi mariajgrimaldi requested a review from bmtcril January 7, 2025 16:27
Copy link

@efortish efortish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The event design suggestions are pretty easy to understand, I think the main goal of this document is to provide clear information on how an event should be design and this document accomplishes that goal, even for someone who has no experience in this topic.

Copy link
Contributor

@sarina sarina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two comments - take them, leave them, or adjust them - but otherwise looks good to me.

docs/decisions/0016-event-design-practices.rst Outdated Show resolved Hide resolved
@mariajgrimaldi
Copy link
Member Author

This is a gentle reminder, @robrap, @Alec4r, and @bmtcril. Can you help review/approve this PR? Let me know if you agree with the ADR. Thanks!

Copy link
Contributor

@robrap robrap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mariajgrimaldi. Looks good. I don't have any blocking comments. Just a variety of thoughts related to the docs in general.

This doc made me wonder about how-to vs adr when it comes to these docs. I don't think there is any perfect answer. I think the most important thing is helping people find this information when they need it.

Related:

  1. We don't have adr vs how-to for OEPs, so there, we sort of use the OEP type of "Architecture" vs "Best Practice", and even there it gets fuzzy which one to use at times.
  2. We used OEPs for cross-open-edx decisions for events before this repo existed. For example: https://open-edx-proposals.readthedocs.io/en/latest/architectural-decisions/oep-0041-arch-async-server-event-messaging.html. I don't know if people would know that event related decisions from before a specific date are listed as OEPs, and after a certain date are dropped as ADRs in this repo. This is something you should consider as part of the FC. You could drop notes in the OEPs stating where all future event-related ADRs live, or you could migrate + note, etc.

@@ -0,0 +1,127 @@
16. Event Design Practices
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: => Event Design Best Practices? Were you intentionally avoiding calling these "best practices"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did, yes. This is mainly because these are opinionated suggestions that not all developers might agree with, although they aren't that controversial. So, I'm okay with calling them good practices, considering that we all agree with them.

Responsibility and Granularity
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- Design events with a single responsibility in mind. Each event should represent a single action or fact that happened in the system. If an event contains multiple actions, consider splitting it into multiple events. For instance, if the course grade is updated to pass or fail, there should be two events: one for the pass action and another for the fail action.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this ADR is about the event design itself, but somewhere you may want to consider adding a note like the following:

Events that are split across multiple actions is an exceptional case where the same event queue/topic should be used to help maintain order across these events.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This note's pretty useful! Thanks. I'll make sure to add it right away.

@sarina
Copy link
Contributor

sarina commented Jan 13, 2025

I don't know if people would know that event related decisions from before a specific date are listed as OEPs, and after a certain date are dropped as ADRs in this repo. This is something you should consider as part of the FC. You could drop notes in the OEPs stating where all future event-related ADRs live, or you could migrate + note, etc.

I like the idea of adding a brief update to the OEP to direct people to look in this repo for ADRs.

@mariajgrimaldi
Copy link
Member Author

Thank you both, @sarina @robrap! I've created this PR to address your suggestions about updating the OEPs: openedx/open-edx-proposals#662

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FC Relates to an Axim Funded Contribution project open-source-contribution PR author is not from Axim or 2U
Projects
Status: Waiting on Author
Development

Successfully merging this pull request may close these issues.

7 participants