hubcio commented on code in PR #3163:
URL: https://github.com/apache/iggy/pull/3163#discussion_r3186975496


##########
core/server-ng/src/config_writer.rs:
##########
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use crate::server_error::ServerNgError;
+use compio::fs::OpenOptions;
+use compio::io::AsyncWriteAtExt;
+use configs::server_ng::ServerNgConfig;
+use std::net::SocketAddr;
+
+/// Write the runtime `current_config.toml` file with the effective bound 
ports.
+///
+/// # Errors
+///
+/// Returns an error if the config cannot be serialized or if the runtime
+/// config file cannot be written and synced.
+pub async fn write_current_config(
+    config: &ServerNgConfig,
+    current_replica_id: Option<u8>,
+    bound_tcp: Option<SocketAddr>,
+    bound_replica: Option<SocketAddr>,
+    bound_tcp_tls: Option<SocketAddr>,
+    bound_quic: Option<SocketAddr>,
+    bound_websocket: Option<SocketAddr>,
+) -> Result<(), ServerNgError> {
+    let mut current_config = config.clone();
+
+    if let Some(bound_client_tcp) = bound_tcp_tls.or(bound_tcp) {
+        // Keep parity with the current server binary: integration harnesses
+        // read `tcp.address` from `runtime/current_config.toml` to discover
+        // the actual port chosen by the OS when binding to port 0.
+        current_config.tcp.address = bound_client_tcp.to_string();
+    }
+    if let Some(bound_quic) = bound_quic {
+        current_config.quic.address = bound_quic.to_string();
+    }
+    if let Some(bound_websocket) = bound_websocket {
+        current_config.websocket.address = bound_websocket.to_string();
+    }
+
+    if current_config.cluster.enabled
+        && let Some(replica_id) = current_replica_id
+    {
+        let node = current_config
+            .cluster
+            .nodes
+            .iter_mut()
+            .find(|node| node.replica_id == replica_id)
+            .ok_or(ServerNgError::ClusterNodeNotFound { replica_id })?;
+        if let Some(bound_client_tcp) = bound_tcp_tls.or(bound_tcp) {
+            node.ports.tcp = Some(bound_client_tcp.port());
+        }
+        if let Some(bound_replica) = bound_replica {
+            node.ports.tcp_replica = Some(bound_replica.port());
+        }
+        if let Some(bound_quic) = bound_quic {
+            node.ports.quic = Some(bound_quic.port());
+        }
+        if let Some(bound_websocket) = bound_websocket {
+            node.ports.websocket = Some(bound_websocket.port());
+        }
+    }
+
+    let runtime_path = current_config.system.get_runtime_path();
+    let config_path = format!("{runtime_path}/current_config.toml");
+    let content =
+        
toml::to_string(&current_config).map_err(ServerNgError::CurrentConfigSerialize)?;
+
+    let mut file = OpenOptions::new()

Review Comment:
   `truncate(true).open` + `write_all_at(0)` + `sync_all` is non-atomic. a 
crash mid-write leaves a partial TOML, and the integration harness reads the 
bound port from this file - so a partial write surfaces as garbage or `port=0`. 
mirror `IggySnapshot::persist` at `core/metadata/src/impls/metadata.rs:91-130`: 
write to a tmp file, fsync, rename, then fsync the parent dir.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to