Uploads: prevent perpetual locked upload

## Issue
- Closes 592 Force clear stuck upload
- It was possible for an upload to stay "locked" e.g. when browser is killed.

## Change
When refreshing or opening a new tab, always clear the locks. The on-going sessions will re-lock them immediately.
This commit is contained in:
infinite-persistence 2022-01-03 15:30:44 +08:00 committed by Thomas Zarebczan
parent fad3f6ed78
commit 1cc2132a28
3 changed files with 29 additions and 2 deletions

View file

@ -1,3 +1,4 @@
// Local Storage keys // Local Storage keys
export const TUS_LOCKED_UPLOADS = 'tusLockedUploads'; export const TUS_LOCKED_UPLOADS = 'tusLockedUploads';
export const TUS_REMOVED_UPLOADS = 'tusRemovedUploads'; export const TUS_REMOVED_UPLOADS = 'tusRemovedUploads';
export const TUS_REFRESH_LOCK = 'tusRefreshLock';

View file

@ -2,7 +2,13 @@
import { handleActions } from 'util/redux-utils'; import { handleActions } from 'util/redux-utils';
import { buildURI } from 'util/lbryURI'; import { buildURI } from 'util/lbryURI';
import { serializeFileObj } from 'util/file'; import { serializeFileObj } from 'util/file';
import { tusLockAndNotify, tusUnlockAndNotify, tusRemoveAndNotify, tusClearRemovedUploads } from 'util/tus'; import {
tusLockAndNotify,
tusUnlockAndNotify,
tusRemoveAndNotify,
tusClearRemovedUploads,
tusClearLockedUploads,
} from 'util/tus';
import * as ACTIONS from 'constants/action_types'; import * as ACTIONS from 'constants/action_types';
import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses';
import { CHANNEL_ANONYMOUS } from 'constants/claim'; import { CHANNEL_ANONYMOUS } from 'constants/claim';
@ -167,6 +173,14 @@ export const publishReducer = handleActions(
if (guid === 'force--update') { if (guid === 'force--update') {
return { ...state, currentUploads }; return { ...state, currentUploads };
} else if (guid === 'refresh--lock') {
// Re-lock all uploads that are in progress under our tab.
const uploadKeys = Object.keys(currentUploads);
uploadKeys.forEach((k) => {
if (currentUploads[k].uploader) {
tusLockAndNotify(k);
}
});
} }
if (!currentUploads[key]) { if (!currentUploads[key]) {
@ -232,6 +246,8 @@ export const publishReducer = handleActions(
} else { } else {
tusClearRemovedUploads(); tusClearRemovedUploads();
} }
tusClearLockedUploads();
} }
return newPublish; return newPublish;

View file

@ -9,7 +9,7 @@
*/ */
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { TUS_LOCKED_UPLOADS, TUS_REMOVED_UPLOADS } from 'constants/storage'; import { TUS_LOCKED_UPLOADS, TUS_REFRESH_LOCK, TUS_REMOVED_UPLOADS } from 'constants/storage';
import { isLocalStorageAvailable } from 'util/storage'; import { isLocalStorageAvailable } from 'util/storage';
import { doUpdateUploadRemove, doUpdateUploadProgress } from 'redux/actions/publish'; import { doUpdateUploadRemove, doUpdateUploadProgress } from 'redux/actions/publish';
@ -105,6 +105,12 @@ export function tusClearRemovedUploads() {
window.localStorage.removeItem(TUS_REMOVED_UPLOADS); window.localStorage.removeItem(TUS_REMOVED_UPLOADS);
} }
export function tusClearLockedUploads() {
if (!localStorageAvailable) return;
window.localStorage.removeItem(TUS_LOCKED_UPLOADS);
window.localStorage.setItem(TUS_REFRESH_LOCK, Math.random());
}
// **************************************************************************** // ****************************************************************************
// Respond to changes from other tabs. // Respond to changes from other tabs.
// **************************************************************************** // ****************************************************************************
@ -117,6 +123,10 @@ export function tusHandleTabUpdates(storageKey: string) {
window.store.dispatch(doUpdateUploadProgress({ guid: 'force--update' })); window.store.dispatch(doUpdateUploadProgress({ guid: 'force--update' }));
break; break;
case TUS_REFRESH_LOCK:
window.store.dispatch(doUpdateUploadProgress({ guid: 'refresh--lock' }));
break;
case TUS_REMOVED_UPLOADS: case TUS_REMOVED_UPLOADS:
// The other tab's store has removed this upload, so it's safe to do the // The other tab's store has removed this upload, so it's safe to do the
// same without affecting rehydration. // same without affecting rehydration.