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

BinarySource supporting ReadableStream #3411

Merged
merged 7 commits into from
Nov 29, 2023

Conversation

dillonstreator
Copy link
Contributor

@dillonstreator dillonstreator commented Nov 28, 2023

BinarySource supporting ReadableStream to better enable streaming

@dillonstreator dillonstreator requested a review from a team as a code owner November 28, 2023 16:04
Copy link

vercel bot commented Nov 28, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
medplum-www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 29, 2023 0:20am
2 Ignored Deployments
Name Status Preview Comments Updated (UTC)
medplum-app ⬜️ Ignored (Inspect) Visit Preview Nov 29, 2023 0:20am
medplum-storybook ⬜️ Ignored (Inspect) Visit Preview Nov 29, 2023 0:20am

Copy link

vercel bot commented Nov 28, 2023

@dillonstreator is attempting to deploy a commit to the Medplum Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

sweep-ai bot commented Nov 28, 2023

Apply Sweep Rules to your PR?

  • Apply: All new business logic should have corresponding unit tests.
  • Apply: Refactor large functions to be more modular.
  • Apply: Add docstrings to all functions and file headers.

Copy link
Member

@ThatOneBro ThatOneBro left a comment

Choose a reason for hiding this comment

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

Overall I think this will be a great change. Just one comment about using ReadableStream instead of Readable so that this will work in the browser as well 👍

packages/core/src/client.test.ts Outdated Show resolved Hide resolved
packages/core/src/client.ts Outdated Show resolved Hide resolved
@dillonstreator dillonstreator changed the title BinarySource supporting Readable BinarySource supporting ReadableStream Nov 28, 2023
packages/core/test.setup.cjs Show resolved Hide resolved
packages/core/src/client.ts Outdated Show resolved Hide resolved
@ThatOneBro
Copy link
Member

Overall this looks really good! I'm excited to get this in

packages/core/package.json Outdated Show resolved Hide resolved
@ThatOneBro
Copy link
Member

Thanks @dillonstreator! Going to merge once all the tests pass 👍 great addition

@ThatOneBro ThatOneBro added this to the November 30, 2023 milestone Nov 28, 2023
@ThatOneBro ThatOneBro added this pull request to the merge queue Nov 29, 2023
Merged via the queue into medplum:main with commit 7c80d0f Nov 29, 2023
13 checks passed
@dillonstreator
Copy link
Contributor Author

dillonstreator commented Nov 29, 2023

@ThatOneBro This PR should be reverted.
I just did some local testing with this and it is not working as intended. xhr.send() can't be repeatedly called with chunks of the payload.
I'm surprised to find very little online about streaming uploads with XMLHttpRequest. Understandably, most efforts appear to be placed into the fetch standard. As I understand it, we couldn't easily support progress tracking with fetch which is why we fallback to XMLHttpRequest.

Additionally, we can't really stream & report progress (relative to the total payload size) unless we have some mechanism of knowing the size of the stream beforehand. With that, if someone provides a ReadableStream as data and an onProgress, should onProgress just no-op and the client use fetch?

I saw this doc comment that @codyebberson & @ThatOneBro wrote about a longer term approach to handling fetching

### node-fetch
At the time of this writing, we use node-fetch version 2.6.7. The developers of node-fetch have admirably taken the position that ESM-only libs are the future. The version 3 series is ESM-only. Unfortunately, our current server configuration is not yet compatible with ESM-only modules (despite many attempts).
Therefore, for now, we keep node-fetch pinned at the latest version in the version 2 series, which continues to receive security fixes.
In the future, there are 2 possibilities:
- As the ESM ecosystem matures, we eventually support an ESM-only dependency.
- For completely unrelated reasons (i.e., upload progress monitoring), we may move to [Axios](https://www.npmjs.com/package/axios), which would eliminate this exception entirely.

Maybe a good time to continue the discussion of moving to Axios?

@ThatOneBro
Copy link
Member

The node-fetch dependency is something we should definitely look at again. As of Node 18, global fetch is now native to Node and so this dependency might be unnecessary since we recently set the minimum Node version to 18.

As for streaming, yeah you're right. I totally forgot that XHR has never supported file streaming. We could do multipart uploads (using Content-Range) but that wouldn't be quite the same as file streaming and would probably not have the desired performance.

In terms of Axios, I'm skeptical it will improve things much on the browser-side of things in regards to streaming. It looks like there are two backends for Axios, namely node, which uses node:http which does support streaming if I remember correctly, but I don't think it does it the same way that fetch does (uses HTTP/1.1 Chunked Transfer Encoding maybe?), and the second is xhr. See: https://github.com/axios/axios/tree/v1.x/lib/adapters

So in the browser it is again probably not possible to do the file streaming while using axios. I think we will have to find a solution with fetch that still has upload progress (surely that exists by now... right?).

I did find this TransformStream solution, which may work, but I haven't tested it extensively. The example seems promising though:
https://stackoverflow.com/a/69400632
There is mention that TransformStream is not supported in browsers other than Chrome yet, but seems support has improved:
https://developer.mozilla.org/en-US/docs/Web/API/TransformStream

I'll probably play around with it later today.

In the meantime, yes we should revert this commit I guess and come back when we have a better solution. If you want to submit a PR reverting it I'll get that in. 👍

Thank you for your diligence in following up on this

dillonstreator added a commit to dillonstreator/medplum that referenced this pull request Nov 29, 2023
@dillonstreator
Copy link
Contributor Author

Opened the revert #3421

Ah didn't know about the minimum Node version of 18 so ya agreed node-fetch is likely irrelevant.

Saw the same SO post and agree it seems quite promising.

@ThatOneBro
Copy link
Member

Yeah for sure! If you want to test it out, feel free. I think I'd also like to know @codyebberson's take on this too

github-merge-queue bot pushed a commit that referenced this pull request Nov 29, 2023
@reshmakh reshmakh added the fhir-datastore Related to the FHIR datastore, includes API and FHIR operations label Dec 1, 2023
medplumbot added a commit that referenced this pull request Dec 2, 2023
Fixes #3391 - setup git in preapare-release-yml (#3448)
Create example bots that use a shared code library (#3441)
Fixes #2789 - support 'delete' subscriptions with bots (#3426) (#3445)
Fixes #3391 - github action for prepare-release.sh (#3443)
Revert "Fixes #2789 - support 'delete' subscriptions with bots (#3426)" (#3444)
Update AWS instructions (#3437)
Bump @adobe/css-tools from 4.3.1 to 4.3.2 (#3440)
Fix ValidBot warnings (#3438)
Fixes #3404 - add Referrer-Policy and Permissions-Policy headers (#3436)
Fixes #2789 - support 'delete' subscriptions with bots (#3426)
Agent source cleanup (#3431)
Stop reviving removed meta properties (#3432)
Create docs for building questionnaires (#3393)
feat(@medplum/core) Add `AbortSignal` support to client's `createBinary` and `createAttachment` methods (#3420)
Fixes #3401 - Handle no AWS credentials in AWS init tool (#3418)
Revert "`BinarySource` supporting `ReadableStream` (#3411)" (#3421)
Add bulleted list of SuperAdmin priveleges (#3408)
Add a note that config must be updated locally when making changes (#3410)
Improve linking for using binary data (#3406)
Fixes #3413 - set meta.author when updating access policy (#3419)
`BinarySource` supporting `ReadableStream` (#3411)
Handle non-string code in formatCoding (#3415)
Fixes #3414 - use ESM in example apps (#3416)
Fixes #3389 - add vercel.json config to examples (#3417)
feat(fhircast): add `heartbeat` event (#3350)
Add note about graphql respecting access policies (#3403)
Fixes #3395 - Build scripts handle no git repo (#3400)
Dependency upgrades (#3397)
Add callout for batch vs transaction bundles (#3399)
Fixes #3395 - Build scripts handle no git repo (#3396)
Improve examples in the include search docs (#3359)
QuestionnaireBuilder Autosave (#3253)
chore(package.json): add `private: true` to root (#3390)
Docs: FHIR Profile Creation & Search (#3357)
github-merge-queue bot pushed a commit that referenced this pull request Dec 2, 2023
Fixes #3391 - setup git in preapare-release-yml (#3448)
Create example bots that use a shared code library (#3441)
Fixes #2789 - support 'delete' subscriptions with bots (#3426) (#3445)
Fixes #3391 - github action for prepare-release.sh (#3443)
Revert "Fixes #2789 - support 'delete' subscriptions with bots (#3426)" (#3444)
Update AWS instructions (#3437)
Bump @adobe/css-tools from 4.3.1 to 4.3.2 (#3440)
Fix ValidBot warnings (#3438)
Fixes #3404 - add Referrer-Policy and Permissions-Policy headers (#3436)
Fixes #2789 - support 'delete' subscriptions with bots (#3426)
Agent source cleanup (#3431)
Stop reviving removed meta properties (#3432)
Create docs for building questionnaires (#3393)
feat(@medplum/core) Add `AbortSignal` support to client's `createBinary` and `createAttachment` methods (#3420)
Fixes #3401 - Handle no AWS credentials in AWS init tool (#3418)
Revert "`BinarySource` supporting `ReadableStream` (#3411)" (#3421)
Add bulleted list of SuperAdmin priveleges (#3408)
Add a note that config must be updated locally when making changes (#3410)
Improve linking for using binary data (#3406)
Fixes #3413 - set meta.author when updating access policy (#3419)
`BinarySource` supporting `ReadableStream` (#3411)
Handle non-string code in formatCoding (#3415)
Fixes #3414 - use ESM in example apps (#3416)
Fixes #3389 - add vercel.json config to examples (#3417)
feat(fhircast): add `heartbeat` event (#3350)
Add note about graphql respecting access policies (#3403)
Fixes #3395 - Build scripts handle no git repo (#3400)
Dependency upgrades (#3397)
Add callout for batch vs transaction bundles (#3399)
Fixes #3395 - Build scripts handle no git repo (#3396)
Improve examples in the include search docs (#3359)
QuestionnaireBuilder Autosave (#3253)
chore(package.json): add `private: true` to root (#3390)
Docs: FHIR Profile Creation & Search (#3357)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fhir-datastore Related to the FHIR datastore, includes API and FHIR operations
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

3 participants