File tree Expand file tree Collapse file tree 1 file changed +30
-1
lines changed Expand file tree Collapse file tree 1 file changed +30
-1
lines changed Original file line number Diff line number Diff line change 1
1
use crate :: { util:: ConnectorService , Result } ;
2
+
3
+ use std:: path:: Path ;
4
+
2
5
use bytes:: Bytes ;
3
6
use hyper:: Body ;
7
+ use tokio:: io:: AsyncWriteExt as _;
8
+ use uuid:: Uuid ;
4
9
5
10
const METADATA_VERSION : u32 = 0 ;
6
11
@@ -123,7 +128,7 @@ impl SyncContext {
123
128
} )
124
129
. unwrap ( ) ;
125
130
126
- tokio :: fs :: write ( path, contents) . await . unwrap ( ) ;
131
+ atomic_write ( path, & contents[ .. ] ) . await . unwrap ( ) ;
127
132
128
133
Ok ( ( ) )
129
134
}
@@ -156,3 +161,27 @@ struct MetadataJson {
156
161
version : u32 ,
157
162
durable_frame_num : u32 ,
158
163
}
164
+
165
+ async fn atomic_write < P : AsRef < Path > > ( path : P , data : & [ u8 ] ) -> Result < ( ) > {
166
+ // Create a temporary file in the same directory as the target file
167
+ let directory = path. as_ref ( ) . parent ( ) . unwrap ( ) ;
168
+
169
+ let temp_name = format ! ( ".tmp.{}" , Uuid :: new_v4( ) ) ;
170
+ let temp_path = directory. join ( temp_name) ;
171
+
172
+ // Write data to temporary file
173
+ let mut temp_file = tokio:: fs:: File :: create ( & temp_path) . await . unwrap ( ) ;
174
+
175
+ temp_file. write_all ( data) . await . unwrap ( ) ;
176
+
177
+ // Ensure all data is flushed to disk
178
+ temp_file. sync_all ( ) . await . unwrap ( ) ;
179
+
180
+ // Close the file explicitly
181
+ drop ( temp_file) ;
182
+
183
+ // Atomically rename temporary file to target file
184
+ tokio:: fs:: rename ( & temp_path, & path) . await . unwrap ( ) ;
185
+
186
+ Ok ( ( ) )
187
+ }
You can’t perform that action at this time.
0 commit comments