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

Cant download Manifest after you abort() it once #2781

Closed
MaxNoetzold opened this issue Aug 12, 2020 · 3 comments
Closed

Cant download Manifest after you abort() it once #2781

MaxNoetzold opened this issue Aug 12, 2020 · 3 comments
Assignees
Labels
status: archived Archived and locked; will not be updated type: bug Something isn't working correctly
Milestone

Comments

@MaxNoetzold
Copy link

MaxNoetzold commented Aug 12, 2020

Have you read the FAQ and checked for duplicate open issues?
Yes

What version of Shaka Player are you using?
3.0.2

Can you reproduce the issue with our latest release version?
Yes (if its 3.0.2)

Can you reproduce the issue with the latest code from master?
Yes

Are you using the demo app or your own custom app?
my own custom app

If custom app, can you reproduce the issue using our demo app?
I dont think that the abort() function is used in the demo app.

What browser and OS are you using?
Chrome 85, Windows 10

For embedded devices (smart TVs, etc.), what model and firmware version are you using?

What are the manifest and license server URIs?

https://storage.googleapis.com/shaka-demo-assets/sintel-mp4-only/dash.mpd

What did you do?

let abortableOperation;
function onDownloadSuccess(storedContent) {
	console.log(storedContent);
	abortableOperation = null;
	startDownload();
}

function onDownloadError(error) {
	console.log(error);
	abortableOperation = null;
	startDownload();
}

function startDownload() {
	abortableOperation = window.storage.store('https://storage.googleapis.com/shaka-demo-assets/sintel-mp4-only/dash.mpd');
	abortableOperation.chain(function(storedContent) { onDownloadSuccess(storedContent)}, function(error) {onDownloadError(error)});
	setTimeout(() => {
		abortableOperation.abort();
	}, 2000);
}
startDownload();

if you start a download and abort it afterwards you can start a download with another manifest but never with the same.

What did you expect to happen?
I expected that the second download just works.

What actually happened?

You immediatly get the 7001 error (abort operation) after every startDownload() call (that is not the first).

@joeyparrish
Copy link
Member

I can reproduce this in an even simpler way in the console with two ops and no cycles or tight timing requirements:

player = video.ui.getControls().getLocalPlayer();
storage = new shaka.offline.Storage(player);
op = storage.store('https://storage.googleapis.com/shaka-demo-assets/sintel-mp4-only/dash.mpd');
setTimeout(() => op.abort(), 2000);
// Wait two seconds, check op.promise, see that it's rejected with OPERATION_ABORTED
op2 = storage.store('https://storage.googleapis.com/shaka-demo-assets/sintel-mp4-only/dash.mpd');
// Check op2.promise, see that it's also rejected with OPERATION_ABORTED

It doesn't seem to matter how long you wait between ops.

@joeyparrish joeyparrish added type: bug Something isn't working correctly and removed needs triage labels Aug 21, 2020
@joeyparrish
Copy link
Member

I suspect that initSegmentDbKeyCache_ and segmentDbKeyCache_ in Storage need to be cleared, perhaps when there are no operations in progress, or when there is an error. Another option might be to refactor to make them part of the state of one store operation, rather than members members of the Storage instance.

These caches form a deduplicating mechanism to prevent fetching and storing the same segment multiple times (for example, if multi-period content has been flattened such that the same segment appears in multiple streams).

Since there is already a ton of state carried on the stack, I think long-term, we should break out private methods, parameters, and stack-based state that make an operation in progress. That could be carried in a separate object with its state in members, which may make both the Storage object and the store operation state more readable and maintainable.

Short-term, to cherry-pick for a bug fix release, we may just move those caches into local variables and pass them from createStreams_ => createStream_ => getInitSegmentDbKey_ & getSegmentDbKey_.

@joeyparrish
Copy link
Member

This bug was introduced in v3.0.0 and does not affect v2.5.x.

@shaka-bot shaka-bot added this to the v3.1 milestone Aug 21, 2020
@joeyparrish joeyparrish self-assigned this Feb 17, 2021
joeyparrish added a commit that referenced this issue Feb 25, 2021
When we started deduplicating storage by caching download results for
identical init segments, we mistakenly also cached download failures
or aborted operations.

This moves the cache to the stack so that Storage does not cache
content across store() calls.

Closes #2781

Change-Id: Ia02ca72c3da3132ae6c55a3832bafc67613df810
@shaka-bot shaka-bot added the status: archived Archived and locked; will not be updated label Apr 19, 2021
@shaka-project shaka-project locked and limited conversation to collaborators Apr 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status: archived Archived and locked; will not be updated type: bug Something isn't working correctly
Projects
None yet
Development

No branches or pull requests

3 participants