-
Notifications
You must be signed in to change notification settings - Fork 0
feat: status page #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
970e2ca
393537c
8d3ada2
d2cdd0d
a70ef01
783aaf0
a98a585
58ce533
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,16 +3,43 @@ use serde::Serialize; | |
| use std::sync::Arc; | ||
|
|
||
| use crate::api::error::ApiResult; | ||
| use crate::api::handlers::get_table_count; | ||
| use crate::api::AppState; | ||
|
|
||
| #[derive(Serialize)] | ||
| pub struct HeightResponse { | ||
| pub block_height: i64, | ||
| pub indexed_at: String, | ||
| } | ||
|
|
||
| #[derive(Serialize)] | ||
| pub struct ChainStatus { | ||
| pub chain_id: u64, | ||
| pub chain_name: String, | ||
| pub block_height: i64, | ||
| pub total_transactions: i64, | ||
| pub total_addresses: i64, | ||
| pub indexed_at: String, | ||
| } | ||
|
|
||
| /// GET /api/status - Lightweight endpoint for current chain status | ||
| /// Returns in <1ms, optimized for frequent polling | ||
| /// GET /api/height - Lightweight endpoint for current block height. | ||
| /// Returns in <1ms, optimized for frequent polling. | ||
| pub async fn get_height(State(state): State<Arc<AppState>>) -> ApiResult<Json<HeightResponse>> { | ||
| let result: (String, chrono::DateTime<chrono::Utc>) = sqlx::query_as( | ||
| "SELECT value, updated_at FROM indexer_state WHERE key = 'last_indexed_block'", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is still blocked on items written to disk, if we batch write then its not really latest height but latest written height. what are your thoughts on doing a internal api on the indexer to talk to the api process to allow direct streaming before writing?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll wait for the SSE refactoring to be merged and than we can read this value directly from the latest block in the buffer 👍 |
||
| ) | ||
| .fetch_one(&state.pool) | ||
| .await?; | ||
|
|
||
| let block_height: i64 = result.0.parse().unwrap_or(0); | ||
|
|
||
| Ok(Json(HeightResponse { | ||
| block_height, | ||
| indexed_at: result.1.to_rfc3339(), | ||
| })) | ||
| } | ||
|
|
||
| /// GET /api/status - Full chain status including chain ID, name, and counts. | ||
| pub async fn get_status(State(state): State<Arc<AppState>>) -> ApiResult<Json<ChainStatus>> { | ||
pthmas marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| let result: (String, chrono::DateTime<chrono::Utc>) = sqlx::query_as( | ||
| "SELECT value, updated_at FROM indexer_state WHERE key = 'last_indexed_block'", | ||
|
|
@@ -22,8 +49,15 @@ pub async fn get_status(State(state): State<Arc<AppState>>) -> ApiResult<Json<Ch | |
|
|
||
| let block_height: i64 = result.0.parse().unwrap_or(0); | ||
|
|
||
| let total_transactions = get_table_count(&state.pool, "transactions").await?; | ||
| let total_addresses = get_table_count(&state.pool, "addresses").await?; | ||
|
|
||
| Ok(Json(ChainStatus { | ||
| chain_id: state.chain_id, | ||
| chain_name: state.chain_name.clone(), | ||
| block_height, | ||
| total_transactions, | ||
| total_addresses, | ||
| indexed_at: result.1.to_rfc3339(), | ||
| })) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,25 @@ | ||
| import client from './client'; | ||
|
|
||
| export interface StatusResponse { | ||
| export interface HeightResponse { | ||
| block_height: number; | ||
| indexed_at: string; // ISO timestamp | ||
| } | ||
|
|
||
| export async function getStatus(): Promise<StatusResponse> { | ||
| const response = await client.get<StatusResponse>('/status'); | ||
| export interface ChainStatusResponse { | ||
| chain_id: number; | ||
| chain_name: string; | ||
| block_height: number; | ||
| total_transactions: number; | ||
| total_addresses: number; | ||
| indexed_at: string; // ISO timestamp | ||
| } | ||
|
|
||
| export async function getStatus(): Promise<HeightResponse> { | ||
| const response = await client.get<HeightResponse>('/height'); | ||
| return response.data; | ||
| } | ||
|
|
||
| export async function getChainStatus(): Promise<ChainStatusResponse> { | ||
| const response = await client.get<ChainStatusResponse>('/status'); | ||
| return response.data; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.