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

State Resource concurrency requirements should be the same as Agent Profile Resource and Activity Profile Resource #1097

Open
thomasturrell opened this issue Oct 27, 2020 · 6 comments

Comments

@thomasturrell
Copy link
Contributor

I am concerned by the section on concurrency.

3.1 Concurrency
...
Client Requirements

The State Resource will permit PUT, POST and DELETE requests without concurrency headers, since state conflicts are unlikely.

In my experience state conflicts are very likely. I have observed it the courses produced by some of the more well known authoring tools.

For example if a user progresses a course on a mobile device and then switches to a laptop the state from the mobile device will be restored onto the laptop however any progress on the laptop will be lost if the user switches back to the mobile device (this can be simulated by simply opening a course in multiple tabs).

I believe that the State Resource shouldn't be an exception and that clients should observe the same concurrency requirements that are required for the Agent Profile Resource and Activity Profile Resource.

I am very open to other peoples experience and suggestions.

@brianjmiller
Copy link
Contributor

Permission does not imply best practice. The vast majority of the current use cases aren't likely to produce a conflict so the spec was left loose in this regards to make it simpler on the LRP side (and frankly the LRS side as well).

Having said that, there is nothing that prevents the LRP from leveraging the concurrency headers, and based on my reading of the location of the statement included above, if it does so, the LRS would have to honor them.

Depending on your reading of the specification you could even probably get away with creating an LRS that could be configured to handle them strictly outside of the context of the conformance test suite.

@thomasturrell
Copy link
Contributor Author

@brianjmiller thank you for your quick response. It's useful to have someone else's perspective on this.

I agree not using concurrency headers is simpler for the the LRP but I would like them to be encouraged to do so because it would be best practice if they did. But I wouldn't suggest that the LRP MUST use concurrency headers.

My understanding from the spec is that the State Resource 'is a scratch area for Learning Record Providers that do not have their own internal storage, or need to persist state across devices'. I would have thought that persisting state across devices was very likely to lead to state conflicts.

It would be helpful if you could give me some examples of the majority of the use cases. My only experience of LRP's using the State Resource has been by Flash/HTML 5 courses created by authoring tools and since they are browser based and often opened in a new tab by the LMS, state conflicts seem to occur frequently. On the flip side I have never seen any course created by authoring tool use the Agent Profile Resource or Activity Profile Resource. My experience has been shaped (or limited!) by the industry I've been in so I don't know how other LRPs from other industries use the State Resource.

It just seems odd to me that an LRP SHOULD use concurrency headers for Agent Profile Resource or Activity Profile Resource but the SHOULD requirement is explicitly removed for LRP's that use the State Resource.

@garemoko
Copy link
Contributor

"since state conflicts are unlikely" does seem to encourage people not to use the headers and at least implies acceptable practice. If as @thomasturrell reports people are seeing state conflicts in practice, this feels like something worth discussing for the next version whenever that may be.

@aaronesilvers
Copy link
Contributor

aaronesilvers commented Jan 24, 2021 via email

@thomasturrell
Copy link
Contributor Author

@aaronesilvers I'm not sure if I understand you correctly, so apologies if my response misses your point.

I'm not talking about real time or near real time concurrence. I'm talking about a user that uses multiple devices many hours (possibly days) apart inadvertently wiping out the progress that they have made in a (lets say Storyline) course.

When a Storyline course is launched it attempts to retrieve the state from the LRS, if it receives the state it loads it otherwise it creates a new one. Every time the user progresses the updated state is sent to the LRS. The Storyline course assumes that the state it holds locally is the single point of truth, after the course has been launched it will not attempt to retrieve the state from the LRS again. If the user opens the course on two devices (say a tablet and a phone) they create a race condition.

This issue isn't limited to Storyline, every LRP I have seen in the wild does the same thing. I'm in not implying that these LRPs have done anything wrong, after all the specification explicitly says conflicts are unlikely (when in reality they are very likely).

The solution is simple, all the LRP needs to do is send the etag for the state every time it mutates it, if there is a conflict the LRP can simply refetch the state from the LRS.

@aaronesilvers
Copy link
Contributor

@thomasturrell my apologies. I needed to read this thread a few more times. I was very much going in a different direction about state. I agree with you that seems like adding the header/etag from an LRP is a best practice we should probably promote a lot more considering the trouble it helps avoid by doing so.

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

No branches or pull requests

4 participants