@@ -30,7 +30,7 @@ public final class FileDownloadDelegate: HTTPClientResponseDelegate {
3030 public typealias Response = Progress
3131
3232 private let filePath : String
33- private let io : NonBlockingFileIO
33+ private( set ) var fileIOThreadPool : NIOThreadPool ?
3434 private let reportHead : ( ( HTTPResponseHead ) -> Void ) ?
3535 private let reportProgress : ( ( Progress ) -> Void ) ?
3636
@@ -47,14 +47,46 @@ public final class FileDownloadDelegate: HTTPClientResponseDelegate {
4747 /// the total byte count and download byte count passed to it as arguments. The callbacks
4848 /// will be invoked in the same threading context that the delegate itself is invoked,
4949 /// as controlled by `EventLoopPreference`.
50- public init (
50+ public convenience init (
5151 path: String ,
52- pool: NIOThreadPool = NIOThreadPool ( numberOfThreads : 1 ) ,
52+ pool: NIOThreadPool ,
5353 reportHead: ( ( HTTPResponseHead ) -> Void ) ? = nil ,
5454 reportProgress: ( ( Progress ) -> Void ) ? = nil
5555 ) throws {
56- pool. start ( )
57- self . io = NonBlockingFileIO ( threadPool: pool)
56+ try self . init ( path: path, pool: . some( pool) , reportHead: reportHead, reportProgress: reportProgress)
57+ }
58+
59+ /// Initializes a new file download delegate and uses the shared thread pool of the ``HTTPClient`` for file I/O.
60+ ///
61+ /// - parameters:
62+ /// - path: Path to a file you'd like to write the download to.
63+ /// - reportHead: A closure called when the response head is available.
64+ /// - reportProgress: A closure called when a body chunk has been downloaded, with
65+ /// the total byte count and download byte count passed to it as arguments. The callbacks
66+ /// will be invoked in the same threading context that the delegate itself is invoked,
67+ /// as controlled by `EventLoopPreference`.
68+ public convenience init (
69+ path: String ,
70+ reportHead: ( ( HTTPResponseHead ) -> Void ) ? = nil ,
71+ reportProgress: ( ( Progress ) -> Void ) ? = nil
72+ ) throws {
73+ try self . init ( path: path, pool: nil , reportHead: reportHead, reportProgress: reportProgress)
74+ }
75+
76+ private init (
77+ path: String ,
78+ pool: NIOThreadPool ? ,
79+ reportHead: ( ( HTTPResponseHead ) -> Void ) ? = nil ,
80+ reportProgress: ( ( Progress ) -> Void ) ? = nil
81+ ) throws {
82+ if let pool = pool {
83+ self . fileIOThreadPool = pool
84+ } else {
85+ // we should use the shared thread pool from the HTTPClient which
86+ // we will get from the `HTTPClient.Task`
87+ self . fileIOThreadPool = nil
88+ }
89+
5890 self . filePath = path
5991
6092 self . reportHead = reportHead
@@ -79,24 +111,33 @@ public final class FileDownloadDelegate: HTTPClientResponseDelegate {
79111 task: HTTPClient . Task < Response > ,
80112 _ buffer: ByteBuffer
81113 ) -> EventLoopFuture < Void > {
114+ let threadPool : NIOThreadPool = {
115+ guard let pool = self . fileIOThreadPool else {
116+ let pool = task. fileIOThreadPool
117+ self . fileIOThreadPool = pool
118+ return pool
119+ }
120+ return pool
121+ } ( )
122+ let io = NonBlockingFileIO ( threadPool: threadPool)
82123 self . progress. receivedBytes += buffer. readableBytes
83124 self . reportProgress ? ( self . progress)
84125
85126 let writeFuture : EventLoopFuture < Void >
86127 if let fileHandleFuture = self . fileHandleFuture {
87128 writeFuture = fileHandleFuture. flatMap {
88- self . io. write ( fileHandle: $0, buffer: buffer, eventLoop: task. eventLoop)
129+ io. write ( fileHandle: $0, buffer: buffer, eventLoop: task. eventLoop)
89130 }
90131 } else {
91- let fileHandleFuture = self . io. openFile (
132+ let fileHandleFuture = io. openFile (
92133 path: self . filePath,
93134 mode: . write,
94135 flags: . allowFileCreation( ) ,
95136 eventLoop: task. eventLoop
96137 )
97138 self . fileHandleFuture = fileHandleFuture
98139 writeFuture = fileHandleFuture. flatMap {
99- self . io. write ( fileHandle: $0, buffer: buffer, eventLoop: task. eventLoop)
140+ io. write ( fileHandle: $0, buffer: buffer, eventLoop: task. eventLoop)
100141 }
101142 }
102143
0 commit comments