Skip to content

Conversation

@jcdyer
Copy link
Contributor

@jcdyer jcdyer commented Oct 13, 2017

Add code to submit completions from verticals on behalf of descendent blocks that aren't scorable and don't implement a custom completion method.

JIRA tickets: N/A (Part of Completion API work)

Discussions: See Completion API document above.

Dependencies: #16112 #16047

Screenshots: N/A

Sandbox URL: Upon request.

Merge deadline: None

Testing instructions:

  1. Create a waffle switch named completion.enable_completion_tracking with is_active set to True.
  2. Find a user that has no completions in the demo course.
    from django.contrib.auth.models import User
    from lms.djangoapps.completion.models import BlockCompletion
    pick_from = [u for u in User.objects.all() if not BlockCompletion.objects.filter(user=u).exists()]
  3. Register for the demo course (if needed)
  4. Visit "Example Week 1: Getting Started -> Lesson 1 - Getting Started -> Getting Started"
  5. Once the page has fully rendered, verify that BlockCompletion.objects.filter(user=user, course_key=CourseKey.from_string('course-v1:edX+DemoX+Demo_course') returns a completion object with a completion value of 1.0 for the HTML block and Discussion block on that page. (A later ticket will exclude discussion blocks from completion tracking).
  6. Visit the second-to-last vertical in the sequential: 3. Visit "Example Week 1: Getting Started -> Lesson 1 - Getting Started -> Interactive questions".
  7. Completion of scorable XBlocks is handled separately. Verify that visiting the page doesn't create a completion for the capa problem on the page.

Author notes and concerns:

  1. There may be more work that could be done to extract this into a CompletionContainerMixin, so implementations could add it to a different block type than verticals if appropriate for their installation, but that feels like an optimization that should be deferred.
  2. I considered pushing the functionality to submit completions to the runtime service as well, but since the runtime itself is needed to publish events, and the runtime is directly available to the block, it didn't seem necessary.
  3. Is there a better way to include the runtime service than hard coding it on the LMS runtime, and making it optional on the vertical?
  4. This will need a follow-up to be more specific about when to complete blocks. It currently marks them complete when the vertical is first visited, but it should do it when the block has has been viewed, which will require checking coordinates of the block's containing element in the viewport. We initially said that it should be when the block
  5. I tried to convert the vertical file to ES6, as suggested by the front-end guidelines, but I couldn't make the import of the bookmark button work. I tried several ways of specifying the path, and asked on the openedx slack instance, but couldn't get it working. I don't think it's worth me putting any more time in, but I imagine it would be pretty straightforward for someone with more javascript understanding.

Reviewers

FYI: @e-kolpakov

Settings: N/A

TODO:

@openedx-webhooks
Copy link

Thanks for the pull request, @jcdyer! It looks like you're a member of a company that does contract work for edX. If you're doing this work as part of a paid contract with edX, you should talk to edX about who will review this pull request. If this work is not part of a paid contract with edX, then you should ensure that there is an OSPR issue to track this work in JIRA, so that we don't lose track of your pull request.

Create an OSPR issue for this pull request.

@jcdyer jcdyer force-pushed the cliff/complete-default-blocks branch from c34f29a to d7b2147 Compare October 17, 2017 18:30
@jcdyer jcdyer force-pushed the cliff/complete-default-blocks branch 2 times, most recently from 75caa96 to 5ee299b Compare October 18, 2017 10:45
@jcdyer
Copy link
Contributor Author

jcdyer commented Oct 18, 2017

@bradenmacdonald I thought so, but I was getting lint errors about const and let being reserved keywords. See: https://build.testeng.edx.org/job/edx-platform-quality-pr/41098/Diff_Quality_Report/

CC @andy-armstrong What's the state of ES6 in edx-platform?

@arizzitano
Copy link
Contributor

@jcdyer @bradenmacdonald is right -- es6/es2015 should be used for new js development. You can't mix es5 and es2015 within the same file, though, so if you are unable to convert the entire file to an es2015 module (transpiled through webpack) it may be a moot point.

@jcdyer
Copy link
Contributor Author

jcdyer commented Oct 18, 2017

Thanks @arizzitano . Converting the whole file shouldn't be hard, though I've got a follow-up question about how to configure it on slack: https://openedx.slack.com/archives/C0EUBSV7D/p1508347878000087.

@jcdyer
Copy link
Contributor Author

jcdyer commented Oct 18, 2017

jenkins run python

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.

@jcdyer: Sorry if this semi-complete review is premature. The ES6 discussion got me confused about what was active.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think the following is any simpler to read?

    getattr(block, 'completion_method', 'completable') == 'completable'
    and not getattr(block, 'has_custom_completion', False)
    and not block.has_score

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, I thought I saw @bradenmacdonald comment somewhere on 'completable' being a named constant, but not seeing that, so just noting it again.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a const-soon. See above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@robrap Here's the -soon joke.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah yes. Thank you again. I like.

Copy link
Contributor

Choose a reason for hiding this comment

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

How about get_view_based_completables, or something of that nature?

Copy link
Contributor

Choose a reason for hiding this comment

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

Minor change just in case someone wants the full set and doesn't realize that some are filtered out?:

Return a set of descendent blocks that this vertical still needs to
mark complete upon viewing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a little explanation? Something like?

# Exclude completed blocks to reduce traffic from client

Copy link
Contributor

Choose a reason for hiding this comment

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

Possibly update name of 'watched_completables' based on other name change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changing to "watched_completable_blocks." I think the "watched" part is still an appropriate descriptor, especially at the template level. These are the blocks that the completion system needs to watch for completion.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe renaming completable to block would make this less confusing?

Copy link
Contributor

Choose a reason for hiding this comment

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

Two possible (untested) name changes captured below.
completable.dataset.completable => block.dataset.completableByViewing

See stackoverflow post for where I took naming conversion from data-completable-by-viewing => dataset.completableByViewing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we have a string constant somewhere? Also, not seeing this used anywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There will be a string constant in the XBlock repo. I'll update this to use that once it lands (possibly a later commit, depending on how long it takes to get this one merged).

Copy link
Contributor

Choose a reason for hiding this comment

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

Same questions/concerns as earlier about rollout. Can this be waffle protected? Maybe we can discuss elsewhere.

Copy link
Contributor

Choose a reason for hiding this comment

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

Note to self: This is where I am leaving off for now because: 1) I have limited time allocated to this and 2) I may have jumped into this review prematurely. I'm getting confused around what reviews are needed when, and I should probably wait for the explicit messages from @jcdyer asking for review. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm having trouble juggling all the PRs right now, too. I'm working toward getting the early ones merged, so there's less to focus on.

@jcdyer jcdyer mentioned this pull request Oct 20, 2017
4 tasks
@jcdyer jcdyer force-pushed the cliff/complete-default-blocks branch 5 times, most recently from 9f6a836 to 5856a1b Compare October 23, 2017 15:04
@robrap
Copy link
Contributor

robrap commented Oct 23, 2017

@jcdyer: As a reminder, I did not review all the code. Please leave an explicit comment when and if @bradenmacdonald and I should review like you did on the others. Thanks.

@jcdyer jcdyer mentioned this pull request Oct 23, 2017
2 tasks
@jcdyer jcdyer force-pushed the cliff/complete-default-blocks branch 3 times, most recently from 31cb2fa to be7e979 Compare October 26, 2017 18:39
@jcdyer
Copy link
Contributor Author

jcdyer commented Oct 26, 2017

This is ready for an (opencraft) review. @mtyaka you are listed as reviewer on this, but you signed up for that in a different sprint, so I understand if you don't have time for reviewing this. I'll let you and @bradenmacdonald decide how to handle this.

@robrap You can hold off until I get thumbs from one of the above, if you prefer.

@jcdyer
Copy link
Contributor Author

jcdyer commented Oct 26, 2017

@mtyaka @bradenmacdonald Cancel that earlier request. It looks like I'm missing some test coverage on the new waffle flag. Let me get that in place, and I'll update with a new review request.

@jcdyer
Copy link
Contributor Author

jcdyer commented Oct 26, 2017

@bradenmacdonald @mtyaka This is ready for review by one of you.

@jcdyer jcdyer force-pushed the cliff/complete-default-blocks branch 2 times, most recently from a33011c to 3311e11 Compare October 27, 2017 14:48
@jcdyer
Copy link
Contributor Author

jcdyer commented Oct 27, 2017

There were some bokchoy errors, because I didn't realize that library content is rendered using the vert_module.html template. I set it up not to track completion. We can discuss if that needs to be handled differently, and perhaps create a new ticket if it does. I suspect the library content module will need to be treated as a custom completable, and track completion of its children independently.

Copy link
Contributor

@bradenmacdonald bradenmacdonald left a comment

Choose a reason for hiding this comment

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

@jcdyer I had some minor feedback, but nothing blocking. This looks good and works well.

  • I tested this: per the nice testing instructions
  • I read through the code
  • I checked for accessibility issues: shouldn't be any, but we'll have to be careful about a11y when adding the "complete on scroll into viewport" functionality.
  • Includes documentation: docstrings and comments at least

This will need a follow-up to be more specific about when to complete blocks. It currently marks them complete when the vertical is first visited, but it should do it when the block has has been viewed, which will require checking coordinates of the block's containing element in the viewport.

Yep. I think it makes sense to defer that until we have a UI for indicating completion status though: otherwise, assuming we collect completion data for some time and then later display it via a UI, users may be surprised to see "uncompleted" blocks scattered throughout units they've already completed, simply because they didn't scroll all the way down the page to see that last discussion block, etc.

Copy link
Contributor

Choose a reason for hiding this comment

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

This docstring doesn't seem to explain very clearly what this method does.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this test could use a docstring - it's not immediately obvious exactly what it's doing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Are these log lines just for development?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I've removed them, and included a comment to explain the early return.

Copy link
Contributor

Choose a reason for hiding this comment

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

If I view a sequential like "Lesson 1 - Getting Started" in the demo course and click from the first vertical to another vertical and then back to the first, I see that it still POSTs a publish_completion event to the server - it has "forgotten" that it already marked the block as complete.

I was going to suggest calling delete block.dataset.completableByViewing; after the AJAX request completes successfully, but I think that each vertical gets rendered from an HTML string when switching verticals in a sequential, so that approach wouldn't work.

If you think it's worth doing, maybe add a global variable to track already-submitted completion events? Or we can ignore the duplicates, as it's not a huge optimization.

@robrap
Copy link
Contributor

robrap commented Oct 31, 2017

I have not yet reviewed this, but just wanted to leave some high-level comments:

  1. I imagine that edX is going to need a batch call before this can be turned on because there are some courses with huge verticals.
  2. There was discussion of a timer before marking (not sure if that was implemented or future). For future required features, it might be helpful to have a TODO with a description of what is coming and/or a link to a Confluence page or JIRA ticket.
  3. For scrolling/focus based events, would each one have a timer or would a quick scroll mark things as complete? This will relate both to the need for batch eventing and/or the implementation of batch eventing. Also, I'm not sure if trying to time this details with also having a UI will work, unless you want to add another flag for whether or not to do this.

One of the assumptions I had was that the Completion API would be implemented and merged such that it could be turned on for edX.org without performance issues. It is ok if work is being chunked to get smaller PRs. But I also want to ensure that some details won't get dropped.

Thanks.

@jcdyer jcdyer force-pushed the cliff/complete-default-blocks branch from 072d1d9 to 74a90df Compare November 10, 2017 20:48
@jcdyer
Copy link
Contributor Author

jcdyer commented Nov 10, 2017

@bradenmacdonald Some of your comments were attached to a particular commit. I rebased against the latest master to resolve merge issues & those comments (about the vertical_student_view.js file) got lost, but I've addressed the issues you mentioned. Ready for another round.

@jcdyer jcdyer force-pushed the cliff/complete-default-blocks branch from ef9e6bd to a587933 Compare November 10, 2017 22:04
@jcdyer
Copy link
Contributor Author

jcdyer commented Nov 13, 2017

jenkins run bokchoy

@jcdyer
Copy link
Contributor Author

jcdyer commented Nov 13, 2017

Failure due to: https://build.testeng.edx.org/job/edx-platform-bok-choy-pr/45642/

Trying rerun.

@bradenmacdonald
Copy link
Contributor

@jcdyer I just gave this another spin. It seems to be working very well; there's no duplicate events when changing tabs in the sequential, nor are there repeat events when refreshing the whole page.

Code in your recent commits looks good to me too. Thanks!

So my 👍 stands.

@jcdyer
Copy link
Contributor Author

jcdyer commented Nov 15, 2017

Great! Thanks, @bradenmacdonald .

@robrap This is now ready for your review.

@jcdyer jcdyer force-pushed the cliff/complete-default-blocks branch from a587933 to 8314a6e Compare November 15, 2017 20:05
@robrap
Copy link
Contributor

robrap commented Nov 15, 2017

@jcdyer: I'm working with the team to get this work assigned and scheduled. I will let you know as soon as I hear.

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 @jcdyer. This should be relatively quick.

// Using a global variable for SEEN_COMPLETABLES because this needs to track
// completables between separate loads of the same vertical (when a learner
// goes from one tab to the next, and then navigates back within a given
// sequential).
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice if this comment more fully stood on its own for someone reading this out of context. For example:

// The vertical marks blocks that are completable by viewing as complete as they
// are seen.  The global variable SEEN_COMPLETABLES tracks blocks between
// separate loads of the same vertical (when a learner goes from one tab to the
// next, and then navigates back within a given sequential) to protect against
// duplicate calls to the server.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy pasting this with a slight tweak to the first sentence to simplify the grammatical structure.

if (block.dataset.completableByViewing === undefined) {
return;
}
if (blockKey && !SEEN_COMPLETABLES.has(blockKey)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a TODO comment regarding outstanding work, possibly including ticket id(s)?
Outstanding work:

  • Limiting server calls via a combo of batching or only viewing in focus/viewport to protect server against verticals with large numbers of blocks.
  • Configurable delay that must expire before counting as complete, so quick navigation doesn't automatically mark everything.

See earlier comment around this:
https://github.com/edx/edx-platform/pull/16234#issuecomment-340757576


def get_completions(self, candidates):
"""
Given an iterable colletion of block_keys in the course, returns a
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: colletion => collection

<div class="vert-mod">
% for idx, item in enumerate(items):
<div class="vert vert-${idx}" data-id="${item['id']}">
<div class="vert vert-${idx}" data-id="${item['id']}" \
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add back indent?

# Support for plugins
web-fragments==0.2.2
xblock==1.0.0
git+https://github.com/edx/XBlock@xblock-1.1.0#egg=XBlock==1.1.0
Copy link
Contributor

Choose a reason for hiding this comment

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

Working on updating. Will be 1.1.1.

Copy link
Contributor

Choose a reason for hiding this comment

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

@jcdyer
Copy link
Contributor Author

jcdyer commented Nov 17, 2017

@robrap. Ready for another look.

@jcdyer
Copy link
Contributor Author

jcdyer commented Nov 17, 2017

Tests don't seem to be running right now. I'll try to get them running again in an hour or so. (FYI @edx/testeng)

@michaelyoungstrom
Copy link
Contributor

Sorry @jcdyer , we've been having issues with Jenkins over the last 2 days. Your tests are running right now, and we'll continue monitoring.

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 @jcdyer. Minor addition when you squash.

Copy link
Contributor

Choose a reason for hiding this comment

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

@jcdyer: Thanks. Can you please change this first line to when you squash?:

// TODO: EDUCATOR-1778

In the future, I may ask you to use "TODO: EDUCATOR-1778" so we can track blockers to enabling for edx.org. Thank you!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great idea.

@jcdyer jcdyer force-pushed the cliff/complete-default-blocks branch from c3ab5b6 to 5dbb084 Compare November 17, 2017 21:46
@pomegranited
Copy link
Contributor

@jcdyer Is there documentation for the edx-platform waffle flags anywhere? Would be worth updating it to include this new one.

@jcdyer
Copy link
Contributor Author

jcdyer commented Nov 20, 2017

@pomegranited I actually don't know if there is a central documentation source for the waffle flags and switches, though I agree it's a little hard to work with them as the prefixing makes it so the full switch name doesn't actually show up anywhere. I'll at least as the full name in a comment on the switch itself, and if @robrap knows of a place to document it, I'll add it there too.

* Vertical marks blocks completed when viewed.
* Functionality is hidden behind a waffle switch
* Submissions from front-end are limited to known-incomplete blocks
* Upgrades xblock to version 1.1.1
* Related future requirements listed in TODO tagged with EDUCATOR-1778
  and relevant opencraft OC-* ticket IDs.

OC-3088
@jcdyer jcdyer force-pushed the cliff/complete-default-blocks branch from 11f8d51 to b8202e4 Compare November 28, 2017 20:07
@jcdyer jcdyer merged commit c1e878f into openedx:master Nov 28, 2017
@edx-pipeline-bot
Copy link
Contributor

EdX Release Notice: This PR has been deployed to the staging environment in preparation for a release to production on Thursday, November 30, 2017.

@bradenmacdonald bradenmacdonald deleted the cliff/complete-default-blocks branch November 29, 2017 22:21
@edx-pipeline-bot
Copy link
Contributor

EdX Release Notice: This PR has been deployed to the production environment.

@edx-pipeline-bot
Copy link
Contributor

EdX Release Notice: This PR has been rolled back from the production environment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants