Support anonymous users with new (Blockstore-based) XBlock Runtime - #22427
Conversation
caf2cb5 to
3a04132
Compare
symbolist
left a comment
There was a problem hiding this comment.
Cool! I tested this out and it is working as expected!
There was a problem hiding this comment.
Hmm, are we calling it v2 runtime or blockstore runtime?
There was a problem hiding this comment.
Technically the v2 runtime can support other backends besides blockstore. But I use the terms somewhat interchangeably.
3a04132 to
32f97a0
Compare
|
Okay, the code seems totally reasonable. But at a high level, doesn't this pose a problem for advanced XBlocks like ORA2 that also store database state and expect actual users? The anonymous courseware work outlined in #18134 created a new view so that XBlocks explicitly had to opt into running in this mode. What's the right behavior for something like ORA2 when viewed in this mode? |
Yes and no. I think ORA2 uses edx-submissions which already accepts a string for the user ID and does not have foreign keys, so this might well be compatible with it. The main concerns would be that unwanted rows accumulate in the edx-submissions database table, and/or that instructors start being prompted to grade submissions by anonymous users who aren't enrolled. (I didn't test ORA because I haven't yet implemented the user service in the new runtime, and it depends on the user service to get data about the user. So it currently just shows an "UNABLE TO LOAD" error message if one tries to view it. But I think that if I wired up the user service, it might "just work", though that may not be desired for the reasons I just mentioned.)
At one level, this is completely compatible with that approach: this low-level change to the runtime enables support for anonymous users and is indifferent to which view is being used. Some higher-level code, such as the LMS itself or Ramshackle or LabXchange, could easily implement logic to request Though I suppose that to prevent exceptionally knowledgeable users who aren't logged in from using the REST API to directly request I could also add a fallback for Also note that this doesn't provide any mechanism for, say, determining which parts of a course can be shown to users who aren't logged in, irrespective of what type of xblocks are used - that would also be done at a higher level. In general, whether or not to show a specific block to a user who isn't logged in should be determined based on the content and the context (e.g. course policies) rather than the block type. Here are some various next steps I can do:
I want to do 1+4, but I think that 1+2+3 is probably the best approach here. What do you think? |
|
Follow up: it looks like capa problems and (But that could be a problem if we want to enable public_view for the new runtime but not the old...) If I do 1+4 above, things will work well, because only the new runtime will define that |
The reason was that the client requirement was only for video and html xblocks to be available for non-logged in users. And since non-read only views would have required additional work, they were out of scope.
Thinking again about this I agree with @ormsbee that we should keep the same behavior as LMS where xblocks opt into being available for non-logged in users by explicitly providing a |
|
Having said so for |
Right. But I don't think that's a good long-term product requirement to stick to. Course authors should be able to enable/disable content for public consumption based on which section of the course is in ("Only allow viewing the first two units before users enroll", or based on other criteria like "allow public viewing of practice questions (which are My preference is still 1+4 - it lets us use capa problems and drag-and-drop in the new runtime and for LabXchange, while allowing some types like ORA2 to opt out, and without impacting the current anonymous access system. Doing 2 would mean that we can't use capa problems in LabXchange for users who aren't logged in, and future course authors wouldn't be able to show prospective students what their assessments will be like (which they could otherwise do by making all content, including problems, in the first few units of the course available anonymously). Or, we can do 2, but I'd want to enable capa and drag-and-drop-v2 for public_view, which might impact existing users of the anonymous courseware feature? |
Yes, that is already the case. However the idea of a separate For Those are my thoughts but I'll defer to @ormsbee preference. |
Oh I see. Is that clearly documented throughout the code? I was definitely confused by that, thinking it was more to do with logged-in status than enrolment. Though it seems odd for XBlocks to be changing their content based on enrolment status - wouldn't it be more consistent to use content groups and put the 1 minute video into a content group that the public cohort sees, and the full video (a separate XBlock) into a content group that enrolled students see? |
|
Let’s do 1, 2, 3. And I’m onboard with the idea of implementing capa’s
public view to check for anonymous state storage and delegate to its
student view based on that.
…On Wed, Dec 18, 2019 at 12:53 PM Braden MacDonald ***@***.***> wrote:
However the idea of a separate public_view is that xblocks can have
separate preview and full views independent of whether the user is logged
in or not. For example, "when someone who is not enrolled in a course but
is signed in, previews a video they are only shown the first 1 minute".
Oh I see. Is that clearly documented throughout the code? I was definitely
confused by that, thinking it was more to do with logged-in status than
enrolment. Though it seems odd for XBlocks to be changing their content
based on enrolment status - wouldn't it be more consistent to use content
groups and put the 1 minute video into a content group that the public
cohort sees, and the full video (a separate XBlock) into a content group
that enrolled students see?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<https://github.com/edx/edx-platform/pull/22427?email_source=notifications&email_token=AAAKFGM7ZDYONTPFDHTOOBLQZJPSBA5CNFSM4JUQR5EKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHG6FBA#issuecomment-567140996>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAKFGL4OGNXXMF6KGYYY3TQZJPSBANCNFSM4JUQR5EA>
.
|
|
@bradenmacdonald: You're right that it's not very clear. I think that my main concern is that the XBlock has control of the situation and has to opt into these new features, so that we're not trying to catch weird edge cases. Also, I agree that we shouldn't use public_view to determine which content students get to see–that's definitely the purview of content groups, for which there is support. From my perspective, the Thanks folks. I've been poking at this during the nights since last weekend because I was worried about the downstream effects but couldn't really pin a decent path. Your comments over the last day have made me feel much more at ease with this direction. |
ormsbee
left a comment
There was a problem hiding this comment.
Minor questions, suggestions, but nothing blocking. Please just squash and add context to the commit message.
There was a problem hiding this comment.
Not necessary for this PR, but this class might be a good place to use the TieredCache utility.
Yeah, I know the naming was confusing. But the view selection currently happens on the basis of enrollment status: |
8ca88c2 to
2f18c1b
Compare
|
@ormsbee @symbolist I have addressed your comments (and implemented "1+2+3") via 2f18c1b89939eddbb3d20245d9e3acded851f452 and open-craft/ramshackle@bb57186. I'm pretty happy with how it's working now. I will now rebase and squash; you can use the commit hash above to see the latest changes. |
2f18c1b to
2f004b3
Compare
There was a problem hiding this comment.
This is a seemingly unrelated change, but I found that the public_view of Video XBlocks wasn't working for anonymous users when this VAL code was used, and we have also been sometimes seeing 500 errors on LX when the edx_video_id is present. Also, this was a bit problematic because it makes a lot of blocking API calls to VAL during XML parsing. So for those three reasons, I think that completely omitting this "update VAL" step when parsing video XML in the new runtime will work much better.
|
Please add the "implementation details" section from your PR message to your commit message. I think it's really informative. Also, please let me know if you want to change the timeout to |
Implementation details: * Anonymous users are assigned a unique ID (like `anon42c08f9996194e2a9339`) which gets stored in the django session. `block.scope_ids.user_id` and `block.runtime.anonymous_student_id` will both return this value. * User state for anonymous users is stored in the django cache and automatically expires as the cache gets pruned. Because user state is stored, anonymous users can use interactive blocks like capa problems. * There is no mechanism for upgrading to a registered account and keeping user state since the user state store for anonymous users (EphemeralKeyValueStore) is completely different than the one for registered users (DjangoKeyValueStore/"CSM"), and has no "list all keys" functionality. * "User State Summary" field values are shared among [recently active] anonymous users but are not shared with registered users. * Anonymous users can only access the `public_view` of XBlocks, not the regular `student_view`.
2f004b3 to
f31dc19
Compare
Sure thing, done!
I've changed it to Should be good to go once the build passes! |
|
Your PR has finished running tests. There were no failures. |
|
EdX Release Notice: This PR has been deployed to the staging environment in preparation for a release to production. |
|
EdX Release Notice: This PR has been deployed to the production environment. |
|
@bradenmacdonald, @symbolist: Just as a heads up, this broke some downstream analytics events analysis code because that code expected numerical user IDs. I should be talking with data eng about next steps tomorrow. |
|
@ormsbee Ok, let me know if I can help. For now it should be safe to just discard entries that aren't numerical. |
|
Although this pull request is already merged, I've created OSPR-5398 so that we can track it in Jira. There is nothing you have to do. No action is needed from your side. Thanks again for your contribution. |
This PR updates the new (blockstore-based) XBlock runtime (python API + REST API) so that it can store state for anonymous (non-registered) users. This can be used to allow people to preview course content (or library content, or any other learning context) without having to register an account.
Implementation details:
anon42c08f9996194e2a9339) which gets stored in the django session.block.scope_ids.user_idandblock.runtime.anonymous_student_idwill both return this value.EphemeralKeyValueStore) is completely different than the one for registered users (DjangoKeyValueStore/"CSM"), and has no "list all keys" functionality.This also fixes the Studio behavior of XBlocks in the new runtime so that they store user state in the cache too, very similar to the way Studio today stores user state in the session. (Before this PR, user state for Studio testing of XBlocks was just stored in a dict that was destroyed after each request-response cycle.)
Manual test instructions
Make sure blockstore is running.
Install/update the very latest version of Ramshackle.
Check out this branch and restart Studio/LMS.
Go to http://localhost:18010/ramshackle/ and find or create a

drag-and-drop-v2XBlock in a content library. Click on "Actions" then right-click "this link" for testing anonymously and open it in an incognito window:Drag some items around then refresh the page or open the same URL in another tab (in the same incognito session) and notice that the state is preserved.
Then try with other XBlock types -
problem,video,html, etc.Running the test suite instructions
Unit tests that require blockstore currently do not run automatically because devstack doesn't yet ship with Blockstore. You need to run them manually:
First, from the
blockstoredirectory, runmake testserverto start a Blockstore instance for testing.Then from
make studio-shellrun the following:Then from
make lms-shellrun the same command but withcms.envs.testchanged tolms.envs.test