@@ -2,10 +2,12 @@ import type { ObjectId } from '../bson';
2
2
import type { Collection } from '../collection' ;
3
3
import type { FindCursor } from '../cursor/find_cursor' ;
4
4
import type { Db } from '../db' ;
5
- import { MongoRuntimeError } from '../error' ;
5
+ import { MongoOperationTimeoutError , MongoRuntimeError } from '../error' ;
6
6
import { type Filter , TypedEventEmitter } from '../mongo_types' ;
7
7
import type { ReadPreference } from '../read_preference' ;
8
8
import type { Sort } from '../sort' ;
9
+ import { CSOTTimeoutContext } from '../timeout' ;
10
+ import { resolveOptions } from '../utils' ;
9
11
import { WriteConcern , type WriteConcernOptions } from '../write_concern' ;
10
12
import type { FindOptions } from './../operations/find' ;
11
13
import {
@@ -48,6 +50,7 @@ export interface GridFSBucketPrivate {
48
50
chunkSizeBytes : number ;
49
51
readPreference ?: ReadPreference ;
50
52
writeConcern : WriteConcern | undefined ;
53
+ timeoutMS ?: number ;
51
54
} ;
52
55
_chunksCollection : Collection < GridFSChunk > ;
53
56
_filesCollection : Collection < GridFSFile > ;
@@ -81,11 +84,11 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
81
84
constructor ( db : Db , options ?: GridFSBucketOptions ) {
82
85
super ( ) ;
83
86
this . setMaxListeners ( 0 ) ;
84
- const privateOptions = {
87
+ const privateOptions = resolveOptions ( db , {
85
88
...DEFAULT_GRIDFS_BUCKET_OPTIONS ,
86
89
...options ,
87
90
writeConcern : WriteConcern . fromOptions ( options )
88
- } ;
91
+ } ) ;
89
92
this . s = {
90
93
db,
91
94
options : privateOptions ,
@@ -109,7 +112,10 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
109
112
filename : string ,
110
113
options ?: GridFSBucketWriteStreamOptions
111
114
) : GridFSBucketWriteStream {
112
- return new GridFSBucketWriteStream ( this , filename , options ) ;
115
+ return new GridFSBucketWriteStream ( this , filename , {
116
+ timeoutMS : this . s . options . timeoutMS ,
117
+ ...options
118
+ } ) ;
113
119
}
114
120
115
121
/**
@@ -122,7 +128,11 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
122
128
filename : string ,
123
129
options ?: GridFSBucketWriteStreamOptions
124
130
) : GridFSBucketWriteStream {
125
- return new GridFSBucketWriteStream ( this , filename , { ...options , id } ) ;
131
+ return new GridFSBucketWriteStream ( this , filename , {
132
+ timeoutMS : this . s . options . timeoutMS ,
133
+ ...options ,
134
+ id
135
+ } ) ;
126
136
}
127
137
128
138
/** Returns a readable stream (GridFSBucketReadStream) for streaming file data from GridFS. */
@@ -135,7 +145,7 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
135
145
this . s . _filesCollection ,
136
146
this . s . options . readPreference ,
137
147
{ _id : id } ,
138
- options
148
+ { timeoutMS : this . s . options . timeoutMS , ... options }
139
149
) ;
140
150
}
141
151
@@ -144,11 +154,27 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
144
154
*
145
155
* @param id - The id of the file doc
146
156
*/
147
- async delete ( id : ObjectId ) : Promise < void > {
148
- const { deletedCount } = await this . s . _filesCollection . deleteOne ( { _id : id } ) ;
157
+ async delete ( id : ObjectId , options ?: { timeoutMS : number } ) : Promise < void > {
158
+ const { timeoutMS } = resolveOptions ( this . s . db , options ) ;
159
+ let timeoutContext : CSOTTimeoutContext | undefined = undefined ;
160
+
161
+ if ( timeoutMS ) {
162
+ timeoutContext = new CSOTTimeoutContext ( {
163
+ timeoutMS,
164
+ serverSelectionTimeoutMS : this . s . db . client . options . serverSelectionTimeoutMS
165
+ } ) ;
166
+ }
149
167
168
+ const { deletedCount } = await this . s . _filesCollection . deleteOne (
169
+ { _id : id } ,
170
+ { timeoutMS : timeoutContext ?. remainingTimeMS }
171
+ ) ;
172
+
173
+ const remainingTimeMS = timeoutContext ?. remainingTimeMS ;
174
+ if ( remainingTimeMS != null && remainingTimeMS <= 0 )
175
+ throw new MongoOperationTimeoutError ( `Timed out after ${ timeoutMS } ms` ) ;
150
176
// Delete orphaned chunks before returning FileNotFound
151
- await this . s . _chunksCollection . deleteMany ( { files_id : id } ) ;
177
+ await this . s . _chunksCollection . deleteMany ( { files_id : id } , { timeoutMS : remainingTimeMS } ) ;
152
178
153
179
if ( deletedCount === 0 ) {
154
180
// TODO(NODE-3483): Replace with more appropriate error
@@ -188,7 +214,7 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
188
214
this . s . _filesCollection ,
189
215
this . s . options . readPreference ,
190
216
{ filename } ,
191
- { ...options , sort, skip }
217
+ { timeoutMS : this . s . options . timeoutMS , ...options , sort, skip }
192
218
) ;
193
219
}
194
220
@@ -198,18 +224,36 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
198
224
* @param id - the id of the file to rename
199
225
* @param filename - new name for the file
200
226
*/
201
- async rename ( id : ObjectId , filename : string ) : Promise < void > {
227
+ async rename ( id : ObjectId , filename : string , options ?: { timeoutMS : number } ) : Promise < void > {
202
228
const filter = { _id : id } ;
203
229
const update = { $set : { filename } } ;
204
- const { matchedCount } = await this . s . _filesCollection . updateOne ( filter , update ) ;
230
+ const { matchedCount } = await this . s . _filesCollection . updateOne ( filter , update , options ) ;
205
231
if ( matchedCount === 0 ) {
206
232
throw new MongoRuntimeError ( `File with id ${ id } not found` ) ;
207
233
}
208
234
}
209
235
210
236
/** Removes this bucket's files collection, followed by its chunks collection. */
211
- async drop ( ) : Promise < void > {
212
- await this . s . _filesCollection . drop ( ) ;
213
- await this . s . _chunksCollection . drop ( ) ;
237
+ async drop ( options ?: { timeoutMS : number } ) : Promise < void > {
238
+ const { timeoutMS } = resolveOptions ( this . s . db , options ) ;
239
+ let timeoutContext : CSOTTimeoutContext | undefined = undefined ;
240
+
241
+ if ( timeoutMS ) {
242
+ timeoutContext = new CSOTTimeoutContext ( {
243
+ timeoutMS,
244
+ serverSelectionTimeoutMS : this . s . db . client . options . serverSelectionTimeoutMS
245
+ } ) ;
246
+ }
247
+
248
+ if ( timeoutContext ) {
249
+ await this . s . _filesCollection . drop ( { timeoutMS : timeoutContext . remainingTimeMS } ) ;
250
+ const remainingTimeMS = timeoutContext . getRemainingTimeMSOrThrow (
251
+ `Timed out after ${ timeoutMS } ms`
252
+ ) ;
253
+ await this . s . _chunksCollection . drop ( { timeoutMS : remainingTimeMS } ) ;
254
+ } else {
255
+ await this . s . _filesCollection . drop ( ) ;
256
+ await this . s . _chunksCollection . drop ( ) ;
257
+ }
214
258
}
215
259
}
0 commit comments