Skip to content

Feature: Add request hooks #36

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

Merged
merged 10 commits into from
Jun 2, 2021
Merged

Conversation

igoroctaviano
Copy link
Contributor

@igoroctaviano igoroctaviano commented May 3, 2021

Example using node-retry to add retry functionality to XHR:

    const client = new api.DICOMwebClient({
      url: server.qidoRoot,
      headers: DICOMWeb.getAuthorizationHeader(server),
      errorInterceptor: errorHandler.getHTTPErrorHandler(),
      requestHooks: [
        (request, metadata) => {
          function faultTolerantRequestSend(...args) {
            const operation = retry.operation({
              retries: 10,
            });
            /**
             * retries: 5,
             * factor: 3,
             * minTimeout: 1 * 1000,
             * maxTimeout: 60 * 1000,
             * randomize: true
             */

            operation.attempt(function(currentAttempt) {
              const originalOnReadyStateChange = request.onreadystatechange;

              request.onreadystatechange = function() {
                originalOnReadyStateChange.call(request);
                if (request.status === 429 || request.status >= 500) {
                  operation.retry(new Error('Attempt failed!'));
                }
              };

              console.debug(`${metadata.url} (attempt: ${currentAttempt})`);
              request.open(metadata.method, metadata.url, true);
              originalRequestSend.call(request, ...args);
            });
          }

          const originalRequestSend = request.send;
          request.send = faultTolerantRequestSend;

          return request;
        },
      ],
    });

@hackermd
Copy link
Member

hackermd commented May 3, 2021

@igoroctaviano this is super cool, but not easy to understand:

const pipe = functions => args => functions.reduce((arg, fn) => fn(arg), args)

If we go for this approach, I would suggest adding

  • Documentation (in the docstring and in the source code) and several examples to describe and demonstrate how this feature is intended to be used
  • Runtime type checks (instanceOf, typeof, etc.) to avoid cryptic error messages, for example if a caller passes an object that is not callable
  • Unit tests
  • Type annotations (we can use the ones we already have in SliM and include them in the library)

@pieper
Copy link
Contributor

pieper commented May 4, 2021

Yes, and while we need to be idiomatic to the languages, it would be great if the functionality and perhaps even some of the naming were consistent with the discussion here:

ImagingDataCommons/dicomweb-client#50

@igoroctaviano igoroctaviano changed the title Feature: Add request enhancers Feature: Add request interceptors May 5, 2021
src/api.js Outdated
@@ -187,6 +187,7 @@ class DICOMwebClient {
}

if (requestInterceptors) {
console.debug('yes')
const metadata = { method, url };
const pipeRequestInterceptors = functions => (args) => functions.reduce((args, fn) => fn(args, metadata), args);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest adding a couple of runtime checks here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. Let me know if I should add more. Thanks.

@hackermd
Copy link
Member

hackermd commented May 7, 2021

@igoroctaviano could we call the option requestHooks rather than requestInterceptors? I think the term hook would be more intuitive and is used by other libraries for similar purposes. What do you think?

@igoroctaviano igoroctaviano changed the title Feature: Add request interceptors Feature: Add request hooks May 12, 2021
@igoroctaviano
Copy link
Contributor Author

@igoroctaviano could we call the option requestHooks rather than requestInterceptors? I think the term hook would be more intuitive and is used by other libraries for similar purposes. What do you think?

Sure, I took it from axios library, where they call these request interceptors but I'm fine with hooks, updated.

@igoroctaviano
Copy link
Contributor Author

@hackermd just pushed an example and updated the existent one to point to dcmjs server.

@pieper
Copy link
Contributor

pieper commented May 26, 2021

It needs to be rebased but otherwise is this ready to be merged?

@igoroctaviano
Copy link
Contributor Author

It needs to be rebased but otherwise is this ready to be merged?

Yes, just waiting review + merge.

@pieper
Copy link
Contributor

pieper commented May 27, 2021

Any further comments @hackermd or should we merge?

Copy link
Member

@hackermd hackermd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great @igoroctaviano! Just a few minor comments/suggestions. Feel free to ignore.

@igoroctaviano igoroctaviano requested a review from hackermd June 2, 2021 11:07
@Punzo
Copy link
Contributor

Punzo commented Jun 2, 2021

@pieper can you please merge this? Thanks!

@hackermd hackermd merged commit db93d2c into dcmjs-org:master Jun 2, 2021
@hackermd
Copy link
Member

hackermd commented Jun 2, 2021

@pieper can you please merge this? Thanks!

@Punzo @igoroctaviano I merged the PR. Let me know if we should draft a new release.

@Punzo
Copy link
Contributor

Punzo commented Jun 2, 2021

@pieper can you please merge this? Thanks!

@Punzo @igoroctaviano I merged the PR. Let me know if we should draft a new release.

yes, please! thanks!

@hackermd
Copy link
Member

hackermd commented Jun 3, 2021

@Punzo @igoroctaviano I released version 0.8.0 (https://github.com/dcmjs-org/dicomweb-client/releases/tag/v0.8.0) and uploaded the new version of the package to npm (https://www.npmjs.com/package/dicomweb-client/v/0.8.0)

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

Successfully merging this pull request may close these issues.

4 participants