yinming commited on
Commit ·
7881083
1
Parent(s): f24a145
Fix data directory path and add keepalive task
Browse files- Dockerfile +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!({
|