增加get-batch调用

This commit is contained in:
somunslotus 2024-06-27 09:16:24 +08:00
parent 12951636fb
commit 16c1fb7b7b
6 changed files with 400 additions and 15 deletions

103
call.go Normal file
View File

@ -0,0 +1,103 @@
package main
import (
"context"
"encoding/json"
"log"
"net/http"
"sync"
"time"
"io/ioutil"
"fmt"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/render"
)
type Run struct {
Hash string `json:"hash"`
}
type RunInfo struct {
RunHash string `json:"run_hash"`
Data map[string]interface{} `json:"data"`
// other fields from the info API response
}
type IndexedRun struct {
Index int `json:"index"`
Run
}
// var host = "http://my-aim-ui-service.aim:43800"
var host = "http://172.20.32.181:30039"
func main() {
r := chi.NewRouter()
r.Use(middleware.Logger)
r.Post("/api/fetch_run_info", fetchRunInfo)
log.Fatal(http.ListenAndServe(":7124", r))
}
func fetchRunInfo(w http.ResponseWriter, r *http.Request) {
var indexedRuns []IndexedRun
body, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Println("read body error:", err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
r.Body.Close()
fmt.Println("request body:", string(body))
if err := json.Unmarshal(body, &indexedRuns); err != nil {
fmt.Println("unmarshal error:", err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
results := fetchRunDetails(indexedRuns)
render.JSON(w, r, results)
}
func fetchRunDetails(indexedRuns []IndexedRun) []map[string]interface{} {
results := make([]map[string]interface{}, len(indexedRuns))
var wg sync.WaitGroup
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
concurrencyLimit := 20
sem := make(chan struct{}, concurrencyLimit)
for _, indexedRun := range indexedRuns {
wg.Add(1)
sem <- struct{}{} // 向通道发送一个值以占用一个槽
go func(indexedRun IndexedRun) {
defer wg.Done()
defer func() { <-sem }() // 从通道中读取一个值以释放一个槽
url := host + "/api/runs/" + indexedRun.Hash + "/info"
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
fmt.Println("fetching details url for run: ", url)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Printf("Failed to fetch details for run %s: %v", indexedRun.Hash, err)
return
}
defer resp.Body.Close()
var data map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
log.Printf("Failed to decode response for run %s: %v", indexedRun.Hash, err)
return
}
data["run_hash"] = indexedRun.Hash
fmt.Println("run details:", data)
results[indexedRun.Index] = data
}(indexedRun)
}
fmt.Println("waiting for all requests to complete...")
wg.Wait()
fmt.Println("all requests completed, returning results:", results)
return results
}

View File

@ -25,26 +25,34 @@ def print_run_details(run):
df = run.dataframe(include_props=False)
print("all params: ", df.to_dict(orient='records'))
props = run.dataframe(include_props=True,include_params=False)
print("props: ", props.to_dict())
# 假设 Run 对象有以下属性
print(f"Run ID: {run.hash}")
print(f"Experiment: {run.experiment}")
print(f"Description: {run.description}")
print(f"Created at: {run.creation_time}")
print(f"Tags: {run.tags}")
# props = run.dataframe(include_props=True,include_params=False)
# print("props: ", props.to_dict())
# # 假设 Run 对象有以下属性
# print(f"Run ID: {run.hash}")
# print(f"Experiment: {run.experiment}")
# print(f"Description: {run.description}")
# print(f"Created at: {run.creation_time}")
# print(f"Tags: {run.tags}")
# params = repo.collect_params_info()
# print("collectparams: ", params)
seq_type = repo.available_sequence_types()
print("available sequence types: ", seq_type)
seq =run.collect_sequence_info("metric", skip_last_value=False)
print("collect_sequence_info: ", seq)
for metric_name, metric_context, metric_run in run.iter_metrics_info():
print(f"Metric: {metric_name}, Context: {metric_context}, Run: {metric_run}")
# 通过metric_name, metric_context, metric_run获取metric的具体值
metric_value = run.get_metric(metric_name, metric_context)
print(f"{metric_name}: {metric_value}")
for metric in run.metrics():
result = metric.values.values_list()
last = metric.values.last()
print(f"{metric.name} result is :{result} ")
print(f"{metric.name}-{metric.context}: {last}")
#
# for metric in run.metrics():
# result = metric.values.values_list()
# last = metric.values.last()
# print(f"{metric.name} result is :{result} ")
# print(f"{metric.name}-{metric.context}: {last}")
#tt = run.collect_sequence_info(sequence_types="{'context': {'subset': 'train'}, 'name': 'loss')}")
#print("collect info is ", tt)
@ -84,7 +92,7 @@ def print_run_details(run):
# # 查询指定的 runs
# hashes_to_find = ["581c75204d134704b3c9ac27", "3dfdf9b3a4b0453790c8c7d0", "34fd862f49f64d9c8c12aa4a"]
query_res = repo.query_runs(query='run.experiment=="experiment-88888"', paginated=True).iter_runs()
query_res = repo.query_runs(query='run.hash=="07cd1e6130c94e76bd48c528"', paginated=True).iter_runs()
#runs = repo.query_runs(query='', report_mode=QueryReportMode.PROGRESS_TUPLE)

37
fetch.sh Normal file
View File

@ -0,0 +1,37 @@
#!/bin/bash
# 要调用的URL
url="http://172.20.32.181:30059/api/runs/07cd1e6130c94e76bd48c528/info"
# 定义一个函数用于发出HTTP请求
fetch_url() {
curl -s -o /dev/null -w "%{http_code}" "$url"
}
# 总共调用次数
total_requests=60
# 每次并发数
concurrent_requests=10
# 计算需要的批次数
batches=$((total_requests / concurrent_requests))
#记录开始时间
start_time=$(date +%s)
# 执行请求
for ((i=0; i<batches; i++)); do
for ((j=0; j<concurrent_requests; j++)); do
fetch_url &
done
wait
done
# 记录结束时间
end_time=$(date +%s)
# 计算总共耗时
total_time=$((end_time - start_time))
# 输出结果
echo "Total time: $total_time seconds"

57
p_server.py Normal file
View File

@ -0,0 +1,57 @@
from fastapi import FastAPI, HTTPException
from aim.sdk.repo import Repo
import httpx
from datetime import datetime
import uvicorn
import traceback
repo_path = 'aim://172.20.32.181:30038'
#repo_path = 'aim://my-aim-server-service.aim:53800'
# host = 'http://my-aim-ui-service.aim:43800'
go_service_host = 'http://172.20.32.186:7124' # Go服务的地址
# 打开 Aim repository
repo = Repo(path=repo_path)
app = FastAPI()
@app.get("/api/runs/search/run")
async def search_runs(query: str = None, paginated: bool = True, offset: str = None, limit: int = None):
try:
print("query is ", query)
print("paginated is ", paginated)
print("offset is ", offset)
print("limit is ", limit)
query_start_time = datetime.now().timestamp()
query_res = repo.query_runs(query=query, paginated=paginated, offset=offset).iter_runs()
runs = [item.run for item in query_res]
query_end_time = datetime.now().timestamp()
query_duration = query_end_time - query_start_time
print("query time is ", query_duration)
# 根据run.creation_time 降序排序
runs = sorted(runs, key=lambda x: x.creation_time, reverse=True)
if paginated and limit:
runs = runs[:limit]
indexed_runs = [{"index": i, "hash": run.hash, "creation_time": run.creation_time} for i, run in enumerate(runs)]
print("indexed_runs:", indexed_runs)
# 将indexed_runs传递给Go服务以获取详细信息
http_start_time = datetime.now().timestamp()
async with httpx.AsyncClient(timeout=20) as client:
response = await client.post(f"{go_service_host}/api/fetch_run_info", json=indexed_runs)
response.raise_for_status()
results = response.json()
print("result len is ", len(results))
http_end_time = datetime.now().timestamp()
http_duration = http_end_time - http_start_time
print("http time is ", http_duration)
return results
except Exception as e:
traceback.print_exc()
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7123)

91
parallel.py Normal file
View File

@ -0,0 +1,91 @@
from fastapi import FastAPI, HTTPException
from aim.sdk.repo import Repo
import httpx
import traceback
import uvicorn
from datetime import datetime
import asyncio
# AIM repository路径和目标服务的主机地址
repo_path = 'aim://172.20.32.181:30058'
host = 'http://172.20.32.181:30059'
# 打开 AIM repository
repo = Repo(path=repo_path)
# 创建 FastAPI 应用实例
app = FastAPI()
# 定义异步函数,用于获取每个 run 的详细信息
async def fetch_run_info(run, results):
try:
# 构建获取信息的 URL
url = f"{host}/api/runs/{run.hash}/info"
# 使用 httpx.AsyncClient 发起异步 GET 请求
async with httpx.AsyncClient() as client:
response = await client.get(url)
response.raise_for_status()
info = response.json()
info['run_hash'] = run.hash # 将 run_hash 添加到返回的信息中
results.append(info) # 将信息添加到结果列表中
except Exception as e:
traceback.print_exc() # 打印异常堆栈信息
raise HTTPException(status_code=500, detail=str(e))
# 定义路由 /api/runs/search/run接收查询参数并发起调用
@app.get("/api/runs/search/run")
async def search_runs(query: str = None, paginated: bool = True, offset: str = None, limit: int = None):
try:
# 记录查询开始时间
query_start_time = datetime.now().timestamp()
# 使用 repo.query_runs 查询符合条件的 runs并获取迭代器
query_res = repo.query_runs(query=query, paginated=paginated, offset=offset).iter_runs()
# 将查询结果中的 run 对象提取到列表中
runs = [item.run for item in query_res]
# 记录查询结束时间和持续时间
query_end_time = datetime.now().timestamp()
query_duration = query_end_time - query_start_time
print("query time is ", query_duration)
# 根据 run.creation_time 降序排序 runs 列表
runs = sorted(runs, key=lambda x: x.creation_time, reverse=True)
results = [] # 初始化结果列表
# 记录 HTTP 请求开始时间
http_start_time = datetime.now().timestamp()
tasks = [] # 初始化任务列表
for run in runs:
# 创建异步任务,并添加到任务列表
task = fetch_run_info(run, results)
tasks.append(task)
# 当任务数达到 10 时,使用 asyncio.gather 并发执行这些任务
if len(tasks) >= 8:
await asyncio.gather(*tasks)
tasks = [] # 清空任务列表,以便下一批任务
# 等待剩余的任务完成
if tasks:
await asyncio.gather(*tasks)
# 记录 HTTP 请求结束时间和持续时间
http_end_time = datetime.now().timestamp()
http_duration = http_end_time - http_start_time
print("http time is ", http_duration)
# 如果是分页模式,并且有限制结果数量,则截取结果列表
if paginated:
results = results[:limit] if limit else results
# 返回最终结果
print("results len is ", len(results))
return results
except Exception as e:
traceback.print_exc() # 打印异常堆栈信息
raise HTTPException(status_code=500, detail=str(e))
# 如果是主程序入口,则运行 FastAPI 应用
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7123)

89
server_refactor.py Normal file
View File

@ -0,0 +1,89 @@
from fastapi import FastAPI, HTTPException
from aim.sdk.repo import Repo
import httpx
import traceback
from datetime import datetime
import uvicorn
repo_path = 'aim://my-aim-server-service.aim:53800'
#repo_path = 'aim://172.20.32.181:30058'
host = 'http://my-aim-ui-service.aim:43800'
#host = 'http://172.20.32.181:30059'
repo = Repo(path=repo_path)
app = FastAPI()
async def fetch_run_info(client, host, run_hash):
try:
url = f"{host}/api/runs/{run_hash}/info"
response = await client.get(url)
response.raise_for_status()
info = response.json()
return info
except httpx.HTTPStatusError as e:
raise HTTPException(status_code=e.response.status_code, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
async def fetch_run_metrics(client, host, run_hash, data):
try:
url = f"{host}/api/runs/{run_hash}/metric/get-batch"
response = await client.post(url, json=data)
response.raise_for_status()
metrics = response.json()
return metrics
except httpx.HTTPStatusError as e:
raise HTTPException(status_code=e.response.status_code, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
def extract_latest_metrics(metrics, name, context):
for metric in metrics:
if metric["name"] == name and metric["context"] == context:
return metric["values"][-1] if metric["values"] else None
return None
@app.get("/api/runs/search/run")
async def search_runs(query: str = None, paginated: bool = True, offset: str = None, limit: int = None):
try:
query_start_time = datetime.now().timestamp()
query_res = repo.query_runs(query=query, paginated=paginated, offset=offset).iter_runs()
runs = [item.run for item in query_res]
query_end_time = datetime.now().timestamp()
query_duration = query_end_time - query_start_time
print("query time is ", query_duration)
runs = sorted(runs, key=lambda x: x.creation_time, reverse=True)
if paginated and limit:
runs = runs[:limit]
results = []
async with httpx.AsyncClient() as client:
for run in runs:
run_info = await fetch_run_info(client, host, run.hash)
data = run_info["traces"]["metric"]
run_metrics = await fetch_run_metrics(client, host, run.hash, data)
for metric in run_metrics:
metric["last_value"] = metric["values"][-1] if metric["values"] else None
run_info["traces"]["metric"] = run_metrics
run_info["run_hash"] = run.hash
results.append(run_info)
http_end_time = datetime.now().timestamp()
http_duration = http_end_time - query_end_time
print("http time is ", http_duration)
return results
except Exception as e:
traceback.print_exc()
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7123)