yinming commited on
Commit
7881083
·
1 Parent(s): f24a145

Fix data directory path and add keepalive task

Browse files
Files changed (2) hide show
  1. Dockerfile +2 -2
  2. server/src/main.rs +63 -2
Dockerfile CHANGED
@@ -43,8 +43,8 @@ COPY --chown=user --from=backend-builder /app/target/release/antigravity-server
43
  # Copy frontend static files
44
  COPY --chown=user --from=frontend-builder /app/dist ./static
45
 
46
- # Create data directory
47
- RUN mkdir -p /home/user/app/data
48
 
49
  # Expose port
50
  EXPOSE 7860
 
43
  # Copy frontend static files
44
  COPY --chown=user --from=frontend-builder /app/dist ./static
45
 
46
+ # Create data directory with accounts subdirectory
47
+ RUN mkdir -p /home/user/app/data/accounts
48
 
49
  # Expose port
50
  EXPOSE 7860
server/src/main.rs CHANGED
@@ -18,12 +18,19 @@ async fn main() {
18
  info!("Starting Antigravity API Proxy Server...");
19
 
20
  // Get data directory
 
21
  let data_dir = if PathBuf::from("/data").exists() {
22
  PathBuf::from("/data")
 
 
23
  } else {
24
- dirs::home_dir()
25
  .expect("Cannot get home directory")
26
- .join(".antigravity_tools")
 
 
 
 
27
  };
28
 
29
  info!("Using data directory: {:?}", data_dir);
@@ -108,6 +115,12 @@ async fn main() {
108
  let addr = format!("0.0.0.0:{}", port);
109
  info!("Server listening on http://{}", addr);
110
 
 
 
 
 
 
 
111
  let listener = tokio::net::TcpListener::bind(&addr)
112
  .await
113
  .expect("Failed to bind address");
@@ -117,6 +130,54 @@ async fn main() {
117
  .expect("Server error");
118
  }
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  /// Health check handler
121
  async fn health_check() -> axum::Json<serde_json::Value> {
122
  axum::Json(serde_json::json!({
 
18
  info!("Starting Antigravity API Proxy Server...");
19
 
20
  // Get data directory
21
+ // Priority: /data (HF persistent) > ./data (current dir) > ~/.antigravity_tools (fallback)
22
  let data_dir = if PathBuf::from("/data").exists() {
23
  PathBuf::from("/data")
24
+ } else if PathBuf::from("./data").exists() {
25
+ PathBuf::from("./data").canonicalize().unwrap_or_else(|_| PathBuf::from("./data"))
26
  } else {
27
+ let home_dir = dirs::home_dir()
28
  .expect("Cannot get home directory")
29
+ .join(".antigravity_tools");
30
+ // Create the directory if it doesn't exist
31
+ let _ = std::fs::create_dir_all(&home_dir);
32
+ let _ = std::fs::create_dir_all(home_dir.join("accounts"));
33
+ home_dir
34
  };
35
 
36
  info!("Using data directory: {:?}", data_dir);
 
115
  let addr = format!("0.0.0.0:{}", port);
116
  info!("Server listening on http://{}", addr);
117
 
118
+ // Start keep-alive background task to prevent HuggingFace Spaces from sleeping
119
+ let keepalive_port = port;
120
+ tokio::spawn(async move {
121
+ keepalive_task(keepalive_port).await;
122
+ });
123
+
124
  let listener = tokio::net::TcpListener::bind(&addr)
125
  .await
126
  .expect("Failed to bind address");
 
130
  .expect("Server error");
131
  }
132
 
133
+ /// Keep-alive background task
134
+ /// Pings the health check endpoint every 5 minutes to prevent HuggingFace Spaces from sleeping
135
+ async fn keepalive_task(port: u16) {
136
+ use tokio::time::{interval, Duration};
137
+
138
+ // Wait 30 seconds for server to start
139
+ tokio::time::sleep(Duration::from_secs(30)).await;
140
+
141
+ let client = reqwest::Client::new();
142
+ let url = format!("http://127.0.0.1:{}/healthz", port);
143
+
144
+ // Check if keepalive is enabled (default: enabled)
145
+ let enabled = std::env::var("KEEPALIVE_ENABLED")
146
+ .map(|v| v != "false" && v != "0")
147
+ .unwrap_or(true);
148
+
149
+ if !enabled {
150
+ info!("Keep-alive task disabled");
151
+ return;
152
+ }
153
+
154
+ // Get interval from env (default: 5 minutes)
155
+ let interval_secs = std::env::var("KEEPALIVE_INTERVAL")
156
+ .ok()
157
+ .and_then(|v| v.parse::<u64>().ok())
158
+ .unwrap_or(300); // 5 minutes
159
+
160
+ info!("Keep-alive task started (interval: {}s)", interval_secs);
161
+
162
+ let mut ticker = interval(Duration::from_secs(interval_secs));
163
+
164
+ loop {
165
+ ticker.tick().await;
166
+
167
+ match client.get(&url).send().await {
168
+ Ok(resp) if resp.status().is_success() => {
169
+ tracing::debug!("Keep-alive ping successful");
170
+ }
171
+ Ok(resp) => {
172
+ tracing::warn!("Keep-alive ping returned status: {}", resp.status());
173
+ }
174
+ Err(e) => {
175
+ tracing::warn!("Keep-alive ping failed: {}", e);
176
+ }
177
+ }
178
+ }
179
+ }
180
+
181
  /// Health check handler
182
  async fn health_check() -> axum::Json<serde_json::Value> {
183
  axum::Json(serde_json::json!({