@@ -13,6 +13,7 @@ import {Status} from "@common/models/job/types";
1313
1414import { MAX_MULTIPART_COUNT , MIN_MULTIPART_SIZE } from "./boundary-const" ;
1515import TransferManager , { TransferManagerConfig } from "./transfer-manager" ;
16+ import singleFlight from "./single-flight" ;
1617
1718// for walk
1819interface StatsWithName extends Stats {
@@ -77,7 +78,9 @@ export default class UploadManager extends TransferManager<UploadJob, Config> {
7778 // if enable skip empty directory upload.
7879 const remoteDirectoryKey = path . dirname ( remoteKey ) + "/" ;
7980 if ( remoteDirectoryKey !== "./" && ! directoryToCreate . get ( remoteDirectoryKey ) ) {
80- this . createDirectory (
81+ const flightKey = destInfo . regionId + destInfo . bucketName + remoteDirectoryKey ;
82+ this . createDirectoryWithSingleFlight (
83+ flightKey ,
8184 qiniuClient ,
8285 {
8386 region : destInfo . regionId ,
@@ -95,9 +98,11 @@ export default class UploadManager extends TransferManager<UploadJob, Config> {
9598 // and in this electron version(nodejs v10.x) read the directory again
9699 // is too waste. so we create later.
97100 // if we are nodejs > v12.12,use opendir API to determine empty.
98- if ( ! this . config . isSkipEmptyDirectory ) {
101+ if ( ! this . config . isSkipEmptyDirectory && ! directoryToCreate . get ( remoteDirectoryKey ) ) {
99102 const remoteDirectoryKey = remoteKey + "/" ;
100- this . createDirectory (
103+ const flightKey = destInfo . regionId + destInfo . bucketName + remoteDirectoryKey ;
104+ this . createDirectoryWithSingleFlight (
105+ flightKey ,
101106 qiniuClient ,
102107 {
103108 region : destInfo . regionId ,
@@ -134,6 +139,9 @@ export default class UploadManager extends TransferManager<UploadJob, Config> {
134139 hooks ?. jobsAdded ?.( ) ;
135140 }
136141
142+ /**
143+ * best to call {@link createDirectoryWithSingleFlight}
144+ */
137145 private async createDirectory (
138146 client : Adapter ,
139147 options : {
@@ -144,6 +152,16 @@ export default class UploadManager extends TransferManager<UploadJob, Config> {
144152 } ,
145153 ) {
146154 await client . enter ( "createFolder" , async client => {
155+ const isDirectoryExists = await client . isExists (
156+ options . region ,
157+ {
158+ bucket : options . bucketName ,
159+ key : options . key ,
160+ } ,
161+ ) ;
162+ if ( isDirectoryExists ) {
163+ return
164+ }
147165 await client . putObject (
148166 options . region ,
149167 {
@@ -163,6 +181,8 @@ export default class UploadManager extends TransferManager<UploadJob, Config> {
163181 } ;
164182 }
165183
184+ private createDirectoryWithSingleFlight = singleFlight ( this . createDirectory )
185+
166186 private createUploadJob (
167187 from : Required < UploadJob [ "options" ] [ "from" ] > ,
168188 to : UploadJob [ "options" ] [ "to" ] ,
0 commit comments