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

Feat/158222 158279 bulk export for file upload types other than s3/gcs #9467

Merged

Conversation

arafubeatbox
Copy link
Contributor

@arafubeatbox arafubeatbox commented Dec 5, 2024

目的

s3/gcs 以外のファイルアップロード設定でも bulk export を可能にする

実装内容

  • s3/gcs でしか許可していなかった bulk export を全てのファイルアップロード設定で有効化
  • PageBulkExportJobCronService で実行される compressAndUploadAsync を修正
    • multipart upload ではなく uploadAttachment を使用するように変更
    • compressAndUploadAsync 内での非同期処理 (非同期で pipeline を実行していた部分) はなくなったため、名前を compressAndUploadAsync -> compressAndUpload に変更
      • PageBulkExportJobCronService 内では await していないため、アップロード処理は変わらず非同期で実行される
  • PageBulkExportJob から multipart upload のリソース記憶用のフィールド (uploadId, uploadKey) を削除

task

https://redmine.weseek.co.jp/issues/158279

Copy link

changeset-bot bot commented Dec 5, 2024

⚠️ No Changeset found

Latest commit: a6a9607

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@@ -164,7 +164,7 @@ export abstract class AbstractFileUploader implements FileUploader {
throw new Error('Multipart upload not available for file upload type');
}

abstract uploadAttachment(readStream: ReadStream, attachment: IAttachmentDocument): Promise<void>;
abstract uploadAttachment(readable: Readable, attachment: IAttachmentDocument): Promise<void>;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Archiver のインスタンスが渡せるように Readable に変更

Copy link
Member

Choose a reason for hiding this comment

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

ここデグレしないか慎重になる必要がある

attachment.js が TypeScript になっていないせいで createAttachment メソッドが型安全じゃない状態。
fs.createReadStream() の返り値は Readable にそのまま入れられる、でいいのだろうか。

Copy link
Member

Choose a reason for hiding this comment

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

デグレしちゃって戻した記録がある

#8981ba286f8

Copy link
Contributor Author

Choose a reason for hiding this comment

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

メモ: attachment.js で createReadStream を使用している部分

const fileStream = fs.createReadStream(file.path, {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

こちらですが、アップロード設定 "Local" と "GCS" でページにファイルを貼って動作確認してみましたが、問題なく動作しました。

ReadStream は Readable を継承しており (参考)、createReadStream は ReadStream のインスタンスを返す (参考) ので、uploadAttachment 内の操作が Readable で完結していればバグは生じなさそうです。

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ただ、すみません、aws と gcs の uploadAttachment の引数の定義を Readable に書き換えるのを忘れており、gcs は ReadStream のメソッドも使っていたため、Readable で完結するように修正しました。
a6a9607

(詳細は apps/app/src/server/service/file-uploader/gcs/index.ts のコメントに記載

@@ -157,7 +157,7 @@ class PageBulkExportJobCronService extends CronService implements IPageBulkExpor
exportPagesToFsAsync.bind(this)(pageBulkExportJob);
}
else if (pageBulkExportJob.status === PageBulkExportJobStatus.uploading) {
await compressAndUploadAsync.bind(this)(user, pageBulkExportJob);
compressAndUpload.bind(this)(user, pageBulkExportJob);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

multipart upload の準備のエラーをキャッチするために await していたが、multipart upload しなくなったため await を除外。
(また、await してしまうと、compressAndUpload 内の uploadAttachment を待つようになってしまう

@arafubeatbox arafubeatbox changed the title Feat/158222 158279 bulk export to normal fs Feat/158222 158279 bulk export for file upload types other than s3/gcs Dec 6, 2024
@arafubeatbox arafubeatbox marked this pull request as ready for review December 6, 2024 01:12
@@ -1,117 +0,0 @@
import { Writable, pipeline } from 'stream';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ファイル名を compress-and-upload.ts に変更

return pageArchiver;
}

function getMultipartUploadWritable(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

このメソッドは削除し、final で実行していた後処理だけ postProcess メソッドとして抽出。

@@ -164,7 +164,7 @@ export abstract class AbstractFileUploader implements FileUploader {
throw new Error('Multipart upload not available for file upload type');
}

abstract uploadAttachment(readStream: ReadStream, attachment: IAttachmentDocument): Promise<void>;
abstract uploadAttachment(readable: Readable, attachment: IAttachmentDocument): Promise<void>;
Copy link
Member

Choose a reason for hiding this comment

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

ここデグレしないか慎重になる必要がある

attachment.js が TypeScript になっていないせいで createAttachment メソッドが型安全じゃない状態。
fs.createReadStream() の返り値は Readable にそのまま入れられる、でいいのだろうか。

@@ -164,7 +164,7 @@ export abstract class AbstractFileUploader implements FileUploader {
throw new Error('Multipart upload not available for file upload type');
}

abstract uploadAttachment(readStream: ReadStream, attachment: IAttachmentDocument): Promise<void>;
abstract uploadAttachment(readable: Readable, attachment: IAttachmentDocument): Promise<void>;
Copy link
Member

Choose a reason for hiding this comment

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

デグレしちゃって戻した記録がある

#8981ba286f8

@@ -121,11 +122,12 @@ class GcsFileUploader extends AbstractFileUploader {
const filePath = getFilePathOnStorage(attachment);
const contentHeaders = new ContentHeaders(attachment);

await myBucket.upload(readStream.path.toString(), {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

元々 ReadStream の path を読み取ってアップロードしていましたが、Readable に変更すると path がないため、これができなくなります。

ここでは ReadStream はパスを渡すためだけのインターフェース化しており、stream としての役割を果たしていません。

stream を使ってアップロードする方法が公式サンプルにあったため、そちらを参考にし、Readable stream を使用するコードに修正しました。
https://github.com/googleapis/nodejs-storage/blob/main/samples/streamFileUpload.js

@yuki-takei yuki-takei merged commit f8dfda8 into feat/page-bulk-export Dec 11, 2024
10 checks passed
@yuki-takei yuki-takei deleted the feat/158222-158279-bulk-export-to-normal-fs branch December 11, 2024 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants