You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -66,6 +69,35 @@ impl Function for DownloadNavigationData {
66
69
typeReturnType = ();
67
70
68
71
asyncfnrun(&mutself) -> Result<Self::ReturnType>{
72
+
self.download_to_temp().await?;
73
+
74
+
// Only close connection if DATABASE_STATE has already been initialized - otherwise we end up unnecessarily copying the bundled data and instantly replacing it (due to initialization logic in database state)
75
+
ifLazy::get(&DATABASE_STATE).is_some(){
76
+
// Drop the current database. We don't do this before the download as there is a chance it will fail, and then we end up with no database open.
/// Download the navigation data zip file to the temp file location
100
+
asyncfndownload_to_temp(&self) -> Result<()>{
69
101
// Figure out total size of download (this request is acting like a HEAD since we don't have those in this environment. Nothing actually gets downloaded since we are constraining the range)
70
102
let request = NetworkRequestBuilder::new(&self.url)
71
103
.context("can't create new NetworkRequestBuilder")?
@@ -86,11 +118,15 @@ impl Function for DownloadNavigationData {
86
118
.ok_or(anyhow!("invalid content-range"))?
87
119
.parse::<usize>()?;
88
120
89
-
// Total amount of chunks to download
121
+
// Total amount of chunks to download. We need to download the data in chunks of DOWNLOAD_CHUNK_SIZE_BYTES to avoid a timeout, so we need to keep track of a "working" accumulation of all responses
90
122
let total_chunks = total_bytes.div_ceil(DOWNLOAD_CHUNK_SIZE_BYTES);
91
123
92
-
// We need to download the data in chunks of DOWNLOAD_CHUNK_SIZE_BYTES to avoid a timeout, so we need to keep track of a "working" accumulation of all responses
93
-
letmut bytes = vec![];
124
+
// Store the download to a file to avoid holding in-memory
125
+
letmut download_file = OpenOptions::new()
126
+
.write(true)
127
+
.create(true)
128
+
.truncate(true)
129
+
.open(DOWNLOAD_TEMP_FILE_PATH)?;
94
130
95
131
for i in0..total_chunks {
96
132
// Calculate the range for the current chunk
@@ -115,20 +151,18 @@ impl Function for DownloadNavigationData {
115
151
.wait_for_data()
116
152
.await?;
117
153
118
-
bytes.write_all(&data)?;
154
+
// Write and force flush to limit how much data we hold in memory at a time (will be a max of DOWNLOAD_CHUNK_SIZE_BYTES)
155
+
download_file.write_all(&data)?;
156
+
download_file.flush()?;
119
157
}
120
158
121
-
// Only close connection if DATABASE_STATE has already been initialized - otherwise we end up unnecessarily copying the bundled data and instantly replacing it (due to initialization logic in database state)
122
-
ifLazy::get(&DATABASE_STATE).is_some(){
123
-
// Drop the current database. We don't do this before the download as there is a chance it will fail, and then we end up with no database open.
0 commit comments