-
Notifications
You must be signed in to change notification settings - Fork 116
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
Chore: Adding download reachability checks to Downloads, Document and Image Viewers #669
Conversation
Verified that @jeremypress has signed the CLA. Thanks for the pull request! |
src/lib/downloadReachability.js
Outdated
* @param {string} downloadHost - Download URL host | ||
* @return {void} | ||
*/ | ||
export function setDownloadHostNotificationShown(downloadHost) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to clean up params for these various methods to make them all consistent
src/lib/downloadReachability.js
Outdated
* @return {boolean} - HTTP response | ||
*/ | ||
export function isCustomDownloadHost(url) { | ||
return url && !url.startsWith(DEFAULT_DOWNLOAD_HOST_PREFIX) && !!url.match(/^https:\/\/dl\d+\./); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move the capture statement to a constant, then you can use it here and in places like replaceDownloadHostWithDefaultUrl()
src/lib/viewers/BaseViewer.js
Outdated
@@ -97,6 +107,9 @@ class BaseViewer extends EventEmitter { | |||
/** @property {boolean} - Whether viewer is being used on a touch device */ | |||
hasTouch; | |||
|
|||
/** @property {boolean} - Has the viewer retried downloading the content */ | |||
haveRetried = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you be a little more descriptive with this property name? haveRetried
is pretty vague
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haveRetriedContentDownload
?
src/lib/viewers/BaseViewer.js
Outdated
handleDownloadError(err, downloadURL) { | ||
if (this.haveRetried) { | ||
/* eslint-disable no-console */ | ||
console.error(err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to put console.error(err)
inside of the code that emits preview_error
events, we can throttle back the number of console
statements that exist in our codebase! Up to you :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do! But we would need to remove them all in one to avoid double printing, so I'm leaving this for now and then we can go back and do a commit where we grab them all.
Add your diagram to the PR description please! |
@@ -745,6 +767,9 @@ class Preview extends EventEmitter { | |||
this.throttledMousemoveHandler | |||
); | |||
|
|||
// Set up the notification | |||
this.ui.setupNotification(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please work with @pramodsum to make sure this doesn't muck with annotations. I remember we've had a few issues with the location of setupNotification()
before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were you able to resolve this @jeremypress @pramodsum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, it wasn't actually annotations related but CSS related. #583
I checked that the draw annotations notification was still good after my change.
src/lib/downloadReachability.js
Outdated
/** | ||
* Replaces the hostname of a download URL with the default hostname, https://dl. | ||
* | ||
* @private |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not private if you're exporting it :) Don't really care if you add @public or not to all of these, but keep it consistent.
errorHandler(err) { | ||
/* eslint-disable no-console */ | ||
console.error(err); | ||
/* eslint-enable no-console */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to take these out? They're stripped out in the production build but are occasionally useful on dev.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm moving them all to the handleDownloadError
call in base viewer so we only need to console.error once for any potential download error.
src/lib/viewers/image/ImageViewer.js
Outdated
@@ -52,13 +53,14 @@ class ImageViewer extends ImageBaseViewer { | |||
|
|||
const { representation, viewer } = this.options; | |||
const template = representation.content.url_template; | |||
const downloadURL = this.createContentUrlWithAuthParams(template, viewer.ASSET); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
downloadUrl* to keep consistent with other Url
in the code
src/lib/Preview.js
Outdated
setDownloadReachability(data.download_url).then(() => { | ||
if (isDownloadHostBlocked()) { | ||
// If download is unreachable, try again with default | ||
openUrlInsideIframe(defaultDownloadUrl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any opportunity for a double download here? e.g. can the first download succeed but then this reachability check fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe so. The only way the reachability check fails is if the network request itself fails. This is different from any bad status 500
, 404
etc. which will be treated as "successes" because we get a valid HTTP status.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately we have no way of checking the success of the download due to it coming from an iframe. @DanDeMicco mentioned other methods that we might want to move to that would give us more control over download status.
src/lib/downloadReachability.js
Outdated
return ( | ||
downloadUrl && !downloadUrl.startsWith(DEFAULT_DOWNLOAD_HOST_PREFIX) && !!downloadUrl.match(DEFAULT_HOST_REGEX) | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does your code work properly on dev with dl.jpress.inside-box.net and dl.app.jpress.inside-box.net? I don't think it's super important for the fallback logic to work on dev since there's only one download host, but please make sure we can't get stuck into some edge case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this works on dev since I only check the DL, but this will have to change due to your comment below.
src/lib/downloadReachability.js
Outdated
* @return {string} - The updated download URL | ||
*/ | ||
export function replaceDownloadHostWithDefault(downloadUrl) { | ||
return downloadUrl.replace(DEFAULT_HOST_REGEX, DEFAULT_DOWNLOAD_HOST_PREFIX); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some AWS or accelerated hosts have weird patterns like https://ec2apne1.boxcloud.com
, I'm not sure your regex would capture that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
womp, that is good information to know. I'll need to rethink my whole custom host/default host checking strategy. Good catch.
src/lib/downloadReachability.js
Outdated
* @param {string} contentTemplate - Content download URL template | ||
* @return {string|undefined} Should the notification be shown | ||
*/ | ||
export function downloadNotificationToShow(contentTemplate) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function signature is a bit confusing to me. The JSDoc for returns implies it should return a {boolean} and JSDoc description implies this should return a notification ID of some kind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This used to return a boolean, I'll update the return description.
@@ -53,3 +54,9 @@ export const LOAD_METRIC = { | |||
downloadResponseTime: 'download_response_time', // Time it took for TTFB when requesting a rep. | |||
fullDocumentLoadTime: 'full_document_load_time' // How long it took to load the document so it could be previewed. | |||
}; | |||
|
|||
// Events around download reachability | |||
export const DOWNLOAD_REACHABILITY_METRICS = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
*/ | ||
handleDownloadError(err, downloadURL) { | ||
if (this.hasRetriedContentDownload) { | ||
this.triggerError(err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may want to make sure that this error complies with our new PreviewError
@@ -82,7 +81,9 @@ class ImageBaseViewer extends BaseViewer { | |||
this.loaded = true; | |||
this.emit(VIEWER_EVENT.load); | |||
}) | |||
.catch(this.errorHandler); | |||
.catch(() => { | |||
// No-op, this prmise should always resolve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems funky to not track an error if it occurs. Can we remove this, and allow for an uncaught error, then (if it's possible for this to error)?
|
||
describe('setDownloadHostFallback()', () => { | ||
it('should set the download host fallback key to be true', () => { | ||
expect(sessionStorage.getItem(DOWNLOAD_HOST_FALLBACK_KEY) === 'true').to.be.false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks a bit weird
expect(sessionStorage.getItem(DOWNLOAD_HOST_FALLBACK_KEY)).to.equal('true')
@@ -163,6 +169,7 @@ class Preview extends EventEmitter { | |||
this.handleFileInfoResponse = this.handleFileInfoResponse.bind(this); | |||
this.handleFetchError = this.handleFetchError.bind(this); | |||
this.handleViewerEvents = this.handleViewerEvents.bind(this); | |||
this.handleViewerMetrics = this.handleViewerMetrics.bind(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot this in my last PR :)
@@ -745,6 +767,9 @@ class Preview extends EventEmitter { | |||
this.throttledMousemoveHandler | |||
); | |||
|
|||
// Set up the notification | |||
this.ui.setupNotification(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, it wasn't actually annotations related but CSS related. #583
I checked that the draw annotations notification was still good after my change.
No description provided.