From cfc162a90316fcd90bbc1475821215eac00adf9e Mon Sep 17 00:00:00 2001 From: Algerasgja <2711181794@qq.com> Date: Wed, 7 May 2025 13:37:23 +0800 Subject: [PATCH 1/4] feat: update waverless configuration and add deployment scripts --- __pycache__/pylib.cpython-38.pyc | Bin 2437 -> 2422 bytes config_easytier.py | 286 ++++++++++++++++++++ middlewares/1.firsttime_deploy_openwhisk.py | 9 + middlewares/1.firsttime_deploy_waverless.py | 11 + middlewares/2.update_waverless_bin.py | 12 + middlewares/3.redeploy_waverless.py | 7 + middlewares/4.debug_waverless.py | 44 +++ middlewares/cluster_config.yml | 11 +- middlewares/waverless/waverless | 2 +- 9 files changed, 376 insertions(+), 6 deletions(-) create mode 100644 config_easytier.py create mode 100644 middlewares/1.firsttime_deploy_openwhisk.py create mode 100644 middlewares/1.firsttime_deploy_waverless.py create mode 100644 middlewares/2.update_waverless_bin.py create mode 100644 middlewares/3.redeploy_waverless.py create mode 100644 middlewares/4.debug_waverless.py diff --git a/__pycache__/pylib.cpython-38.pyc b/__pycache__/pylib.cpython-38.pyc index 10fc8c9bd154e0d25b404162d203b74ea2cbe317..7cf33e3bd0302506c98fd4f5d5cc6ae10e316ea1 100644 GIT binary patch delta 334 zcmY+;y-EW?5C?GQZrxq=PV`I>kh|;|!JL=`y|WSI1QqiFHZ~R_n8uGud;klpG{PWQ z+gVB;A|Uz#_X_qFg5Zpu3;Sbs=fBI`FMUP9aTv}{@p9Yd;x!lnwCD-kcmhp;6Z-Ua zp*GI^BY>E0)Cd~%qaGI;{GihP%fUGgGans2Prq~PN;`1$pzHj}i*CX)edwf=Fs8z) z&=ThU6UZ@P4tNhNV?lxStipuWO~I3#niLYcGd*b2o9V?X9QuZx3OcyKW#(62|GHAQ zJQ7CKwK?Q;X7|$$H&Mda75=gcH>KVZBAVE;EV#@9tjmoS7KJq-6y}AR5DPLYwuM|M I=x}E57wybHb^rhX delta 330 zcmW;G%}T>S5C?FliJMiDqK0Dq%7;}jmqckBL68ax7Ed1ZuF?nr6`3fW6+HDg28wY*nNO?dW4{Qp7(lZ+08L# zMH0t@S6Bil>8r8{wZW{h3*ga-*@u9B%!i49=S!7e6d7Jc28KkVpIkap0fcm`>JZVh zYQQ{wC~w$|i#&nLLPX!HKJ9bd;ag}%g9*B#P4sEbYVq2AD+Hg=>Ow;AR(GMnO@FXa zLX0uT$S5oMWocgXesn3&O=#1B-VRr}h|-K}!m!uGrsS63(wpvdQjU?0GxDN@Nnu5B UgsM;zJVCySiO?2OO2@YT0opD^_W%F@ diff --git a/config_easytier.py b/config_easytier.py new file mode 100644 index 0000000..e15495b --- /dev/null +++ b/config_easytier.py @@ -0,0 +1,286 @@ +#!/usr/bin/env python3 + +########################################### +# EasyTier 配置参数 +########################################### +# 网络名称,确保唯一性 +NETWORK_NAME = "cuit_cloud" +# 网络密钥,用于加密通信 +NETWORK_SECRET = "827385543" +# 是否使用官方公共节点 +USE_PUBLIC_NODE = True +# 官方公共节点地址 +PUBLIC_NODE = "tcp://115.29.224.208:11010" +# 本地监听地址(多个进程需要避免端口冲突) +LISTEN_PORT = "11010" +# ipv4 +IPV4="10.126.126.78" +# 是否启用子网代理 +ENABLE_SUBNET_PROXY = False +# 要代理的子网(如果启用子网代理) +SUBNET_TO_PROXY = "192.168.1.0/24" +########################################### + + + +import os +import sys + +# 切换到脚本所在目录 +script_dir = os.path.dirname(os.path.abspath(__file__)) +os.chdir(script_dir) + +########################################### +# 路径配置 +########################################### +# 下载目录 +DOWNLOAD_DIR = '/teledeploy_secret/bin_easytier' +# 安装目录 +INSTALL_DIR = os.path.join(DOWNLOAD_DIR, 'install') +# 可执行文件名 +EXEC_NAMES = ['easytier-cli', 'easytier-core', 'easytier-web'] +MAIN_EXEC = 'easytier-core' +# 可执行文件的完整路径 +EXEC_PATHS = {name: os.path.join(INSTALL_DIR, 'easytier', name) for name in EXEC_NAMES} +# 软链接路径 +LINK_PATHS = {name: os.path.join('/usr/bin', name) for name in EXEC_NAMES} +# 主软链接路径 +MAIN_LINK = os.path.join('/usr/bin', 'easytier') + + +import subprocess +import platform +import shutil +import time +import urllib.request +import zipfile +import os +from pathlib import Path + +def run_with_root(cmd): + """使用root权限运行命令,如果不是root用户则添加sudo""" + if isinstance(cmd, list): + cmd = ' '.join(cmd) + if os.geteuid() != 0: + cmd = 'sudo ' + cmd + return os.system(cmd) + +def check_system(): + """检查系统环境""" + if platform.system() != "Linux": + print("目前只支持 Linux 系统") + sys.exit(1) + + # 检查必要的命令是否存在 + required_commands = ['curl', 'tar', 'systemctl'] + for cmd in required_commands: + if shutil.which(cmd) is None: + print(f"缺少必要的命令: {cmd}") + sys.exit(1) + +def verify_zip_file(file_path): + """验证zip文件是否有效""" + try: + # 检查文件是否存在且非空 + if not os.path.exists(file_path) or os.path.getsize(file_path) == 0: + return False + + # 尝试打开zip文件 + with zipfile.ZipFile(file_path, 'r') as zip_ref: + # 检查zip文件完整性 + if zip_ref.testzip() is not None: + return False + # 检查是否包含 easytier 文件 + file_list = zip_ref.namelist() + return any('easytier' in f.lower() for f in file_list) + + except zipfile.BadZipFile: + return False + except Exception: + return False + +def show_progress(count, block_size, total_size): + """显示下载进度""" + if total_size > 0: + percent = min(100, count * block_size * 100 / total_size) + # 计算进度条长度,总长50字符 + bar_len = 50 + filled_len = int(bar_len * count * block_size / total_size) + bar = '=' * filled_len + '-' * (bar_len - filled_len) + # 计算下载速度和已下载大小 + downloaded = count * block_size + downloaded_mb = downloaded / (1024 * 1024) + total_mb = total_size / (1024 * 1024) + # 输出进度信息 + print(f'\r[下载进度] [{bar}] {percent:.1f}% ({downloaded_mb:.1f}MB/{total_mb:.1f}MB)', end='') + if count * block_size >= total_size: + print() # 下载完成后换行 + +def download_easytier(): + """下载最新版本的 EasyTier到指定目录""" + easytier_zip = os.path.join(DOWNLOAD_DIR, 'easytier.zip') + + try: + need_download = True + + # 检查已存在的文件 + if os.path.exists(easytier_zip): + print("检查已下载的文件...") + if verify_zip_file(easytier_zip): + print("使用已下载的 EasyTier 安装包") + need_download = False + else: + print("已下载的文件无效,将重新下载") + os.remove(easytier_zip) + + # 下载文件 + if need_download: + print("正在下载 EasyTier...") + os.makedirs(DOWNLOAD_DIR, exist_ok=True) + download_url = "https://github.com/EasyTier/EasyTier/releases/download/v2.2.0/easytier-linux-x86_64-v2.2.0.zip" + + # 使用 urllib 下载文件,显示进度 + try: + urllib.request.urlretrieve(download_url, easytier_zip, show_progress) + except urllib.error.URLError as e: + raise Exception(f"下载失败: {str(e)}") + + # 验证新下载的文件 + if not verify_zip_file(easytier_zip): + raise Exception("下载的文件无效,请检查网络连接") + + # 解压文件 + print("正在解压文件...") + # 解压之前要rm INSTALL_DIR + os.system("rm -rf " + INSTALL_DIR) + os.makedirs(INSTALL_DIR, exist_ok=True) + + with zipfile.ZipFile(easytier_zip, 'r') as zip_ref: + # 查看解压后的文件结构 + file_list = zip_ref.namelist() + print("文件列表:", file_list) + + # 解压文件 + zip_ref.extractall(INSTALL_DIR) + + # 检查解压后的目录结构 + print("安装目录内容:") + os.system(f"ls -la {INSTALL_DIR}") + + # 如果目录不存在,创建它 + extracted_dir = os.path.join(INSTALL_DIR, 'easytier') + if not os.path.exists(extracted_dir): + os.makedirs(extracted_dir) + # 移动所有可执行文件到这个目录 + for exec_name in EXEC_NAMES: + src = os.path.join(INSTALL_DIR, f'easytier-linux-x86_64/{exec_name}') + dst = os.path.join(extracted_dir, exec_name) + if os.path.exists(src): + os.rename(src, dst) + else: + raise Exception(f"未找到可执行文件: {exec_name}") + + # 检查所有可执行文件是否存在 + for exec_name in EXEC_NAMES: + if not os.path.exists(EXEC_PATHS[exec_name]): + raise Exception(f"解压失败,未找到 {exec_name} 可执行文件") + # 设置可执行权限 + os.chmod(EXEC_PATHS[exec_name], 0o755) + + # 创建软链接 + for exec_name in EXEC_NAMES: + if os.path.exists(LINK_PATHS[exec_name]): + run_with_root(f'rm -rf {LINK_PATHS[exec_name]}') + run_with_root(f'ln -s {EXEC_PATHS[exec_name]} {LINK_PATHS[exec_name]}') + + # 创建主软链接 (easytier -> easytier-core) + if os.path.exists(MAIN_LINK): + run_with_root(f'rm -rf {MAIN_LINK}') + run_with_root(f'ln -s {EXEC_PATHS[MAIN_EXEC]} {MAIN_LINK}') + + + except Exception as e: + if os.path.exists(easytier_zip): + os.remove(easytier_zip) + raise e + +def create_systemd_service(): + """创建并启用 systemd 服务""" + print("\n开始配置 EasyTier 服务...") + + # 准备配置命令 + cmd = [ + LINK_PATHS[MAIN_EXEC], + '--network-name', NETWORK_NAME, + '--network-secret', NETWORK_SECRET, + '-i', # 使用DHCP自动分配IP + IPV4 + ] + + if USE_PUBLIC_NODE: + # 使用公共节点 + cmd.extend(['-p', PUBLIC_NODE]) + + # 如果不使用公共节点,则监听本地地址 + cmd.extend(['--listeners', LISTEN_PORT]) + + # 生成systemd服务文件 + service_content = f"""[Unit] +Description=EasyTier Service +After=network.target + +[Service] +Type=simple +ExecStart={' '.join(cmd)} +Restart=always +User=root + +[Install] +WantedBy=multi-user.target +""" + + # 写入服务文件 + service_path = '/etc/systemd/system/easytier.service' + with open('/tmp/easytier.service', 'w') as f: + f.write(service_content) + run_with_root(f'mv /tmp/easytier.service {service_path}') + + # 启用并启动服务 + run_with_root('systemctl daemon-reload') + run_with_root('systemctl enable easytier') + run_with_root('systemctl restart easytier') + + print("EasyTier 服务配置完成!") + + + +def check_installation(): + """检查 EasyTier 是否已安装""" + return os.path.exists('/opt/easytier/easytier') + +def main(): + try: + check_system() + download_easytier() + create_systemd_service() + + # 等待服务启动 + time.sleep(2) + + # 显示状态 + print("\n当前配置信息:") + print(f"网络名称: {NETWORK_NAME}") + if USE_PUBLIC_NODE: + print(f"使用公共节点: {PUBLIC_NODE}") + else: + print(f"监听地址: {LISTEN_PORT}") + + print("\n使用以下命令查看服务状态:") + print("systemctl status easytier") + + except Exception as e: + print(f"错误: {str(e)}") + sys.exit(1) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/middlewares/1.firsttime_deploy_openwhisk.py b/middlewares/1.firsttime_deploy_openwhisk.py new file mode 100644 index 0000000..3ffa63a --- /dev/null +++ b/middlewares/1.firsttime_deploy_openwhisk.py @@ -0,0 +1,9 @@ +import os,sys +CUR_FDIR = os.path.dirname(os.path.abspath(__file__)); cur_scan=CUR_FDIR; scan=[["pylib.py" in os.listdir(cur_scan),cur_scan,exec('global cur_scan;cur_scan=os.path.join(cur_scan, "..")')] for _ in range(10)]; found_pylib=[x[0] for x in scan]; pylib_dir_idx=found_pylib.index(True); assert pylib_dir_idx>=0, "pylib.py not found"; print(scan[pylib_dir_idx][1]); ROOT_DIR=os.path.abspath(os.path.join(CUR_FDIR, scan[pylib_dir_idx][1])); sys.path.append(ROOT_DIR) +import pylib + +os.chdir("openwhisk") + +pylib.os_system_sure(f"python3 1.prepare.py") +pylib.os_system_sure(f"python3 3.deploy_ow.py") + diff --git a/middlewares/1.firsttime_deploy_waverless.py b/middlewares/1.firsttime_deploy_waverless.py new file mode 100644 index 0000000..1cbf61e --- /dev/null +++ b/middlewares/1.firsttime_deploy_waverless.py @@ -0,0 +1,11 @@ +import os,sys +CUR_FDIR = os.path.dirname(os.path.abspath(__file__)); cur_scan=CUR_FDIR; scan=[["pylib.py" in os.listdir(cur_scan),cur_scan,exec('global cur_scan;cur_scan=os.path.join(cur_scan, "..")')] for _ in range(10)]; found_pylib=[x[0] for x in scan]; pylib_dir_idx=found_pylib.index(True); assert pylib_dir_idx>=0, "pylib.py not found"; print(scan[pylib_dir_idx][1]); ROOT_DIR=os.path.abspath(os.path.join(CUR_FDIR, scan[pylib_dir_idx][1])); sys.path.append(ROOT_DIR) +import pylib + +os.chdir(CUR_FDIR) +pylib.os_system_sure(f"telego cmd --cmd deploy/bin_waverless2/prepare") +# pylib.os_system_sure(f"telego cmd --cmd deploy/bin_waverless2/upload") + +pylib.os_system_sure(f"telego cmd --cmd deploy/dist_waverless/prepare") +# pylib.os_system_sure(f"telego cmd --cmd deploy/dist_waverless/upload") +# pylib.os_system_sure(f"telego cmd --cmd deploy/dist_waverless/apply") diff --git a/middlewares/2.update_waverless_bin.py b/middlewares/2.update_waverless_bin.py new file mode 100644 index 0000000..fa1f541 --- /dev/null +++ b/middlewares/2.update_waverless_bin.py @@ -0,0 +1,12 @@ +import os,sys +CUR_FDIR = os.path.dirname(os.path.abspath(__file__)); cur_scan=CUR_FDIR; scan=[["pylib.py" in os.listdir(cur_scan),cur_scan,exec('global cur_scan;cur_scan=os.path.join(cur_scan, "..")')] for _ in range(10)]; found_pylib=[x[0] for x in scan]; pylib_dir_idx=found_pylib.index(True); assert pylib_dir_idx>=0, "pylib.py not found"; print(scan[pylib_dir_idx][1]); ROOT_DIR=os.path.abspath(os.path.join(CUR_FDIR, scan[pylib_dir_idx][1])); sys.path.append(ROOT_DIR) +import pylib + +os.chdir(CUR_FDIR) + +pylib.os_system(f"rm -rf waverless/bin_waverless2/prepare_cache/waverless_amd64") +pylib.os_system(f"rm -rf waverless/bin_waverless2/prepare_cache/waverless_entry_amd64") +pylib.os_system_sure(f"telego cmd --cmd deploy/bin_waverless2/prepare") +pylib.os_system_sure(f"telego cmd --cmd deploy/bin_waverless2/upload") + + diff --git a/middlewares/3.redeploy_waverless.py b/middlewares/3.redeploy_waverless.py new file mode 100644 index 0000000..7621d11 --- /dev/null +++ b/middlewares/3.redeploy_waverless.py @@ -0,0 +1,7 @@ +import os,sys +CUR_FDIR = os.path.dirname(os.path.abspath(__file__)); cur_scan=CUR_FDIR; scan=[["pylib.py" in os.listdir(cur_scan),cur_scan,exec('global cur_scan;cur_scan=os.path.join(cur_scan, "..")')] for _ in range(10)]; found_pylib=[x[0] for x in scan]; pylib_dir_idx=found_pylib.index(True); assert pylib_dir_idx>=0, "pylib.py not found"; print(scan[pylib_dir_idx][1]); ROOT_DIR=os.path.abspath(os.path.join(CUR_FDIR, scan[pylib_dir_idx][1])); sys.path.append(ROOT_DIR) +import pylib + +os.chdir(CUR_FDIR) + +pylib.os_system_sure(f"telego cmd --cmd deploy/dist_waverless/apply/default") diff --git a/middlewares/4.debug_waverless.py b/middlewares/4.debug_waverless.py new file mode 100644 index 0000000..53e78a6 --- /dev/null +++ b/middlewares/4.debug_waverless.py @@ -0,0 +1,44 @@ +import subprocess, sys, os +import json + +def get_pods_on_node(node_name): + try: + # 执行 kubectl 命令获取节点上的 Pod 列表 + result = subprocess.run( + ["kubectl", "get", "pods", "--all-namespaces", "-o", "json"], + capture_output=True, + text=True, + check=True + ) + + # 解析 JSON 输出 + pods = json.loads(result.stdout) + + # 筛选出指定节点上的 Pod + pods_on_node = [ + pod for pod in pods['items'] + if pod['spec']['nodeName'] == node_name + ] + + return pods_on_node + + except subprocess.CalledProcessError as e: + print(f"Error executing kubectl command: {e}") + return [] + except json.JSONDecodeError as e: + print(f"Error parsing JSON output: {e}") + return [] + +# 示例调用 +if len(sys.argv) < 2: + print("Usage: python script.py ") + sys.exit(1) + +node_name = sys.argv[1] +pods = get_pods_on_node(node_name) +for pod in pods: + # print(f"Pod Name: {pod['metadata']['name']} Namespace: {pod['metadata']['namespace']}") + podname=pod['metadata']['name'] + if podname.find("waverless")>=0: + print(f"Pod Name: {podname} Namespace: {pod['metadata']['namespace']}") + os.system(f"kubectl logs -f -n {pod['metadata']['namespace']} {podname}") \ No newline at end of file diff --git a/middlewares/cluster_config.yml b/middlewares/cluster_config.yml index a6a88fa..542822f 100644 --- a/middlewares/cluster_config.yml +++ b/middlewares/cluster_config.yml @@ -1,16 +1,17 @@ # lab1: # ip: 192.168.31.162 # is_master: -lab2: - ip: 192.168.31.87 - is_master: +# lab2: +# ip: 192.168.31.87 + lab3: ip: 192.168.31.96 + is_master: # lab7: # ip: 192.168.31.89 -# lab8: -# ip: 192.168.31.54 +lab8: + ip: 192.168.31.54 # lab9: # ip: 192.168.31.9 # is_master: diff --git a/middlewares/waverless/waverless b/middlewares/waverless/waverless index 1778957..39e6ad6 160000 --- a/middlewares/waverless/waverless +++ b/middlewares/waverless/waverless @@ -1 +1 @@ -Subproject commit 177895768f85c7c063cee89997dbae229f5ecf51 +Subproject commit 39e6ad6a144db58b0a457f30f2fc027e051e0d8f From 52e4dd3ef4ae7c238c2c2707589590b55addd3df Mon Sep 17 00:00:00 2001 From: ActivePeter <1020401660@qq.com> Date: Wed, 7 May 2025 15:10:47 +0800 Subject: [PATCH 2/4] ygy --- bencher/Cargo.lock | 1 + bencher/Cargo.toml | 9 +- bencher/app_fn_entries.yaml | 95 ++++++ bencher/bench.yaml | 10 - bencher/scripts/run_with_all_log.sh | 4 + .../src/{ => _deperacated}/demo_img_resize.rs | 0 .../src/{ => _deperacated}/demo_parallel.rs | 0 .../src/{ => _deperacated}/demo_sequential.rs | 0 .../src/{ => _deperacated}/demo_word_count.rs | 0 bencher/src/main.rs | 300 ++++++++++-------- bencher/src/mode_bench.rs | 3 + bencher/src/mode_call_once.rs | 120 +++++++ bencher/src/mode_first_call.rs | 65 ++++ bencher/src/mode_prepare.rs | 5 + bencher/src/parse.rs | 117 ++++++- bencher/src/parse_app.rs | 35 -- bencher/src/response.rs | 7 + bencher/src/test_call_once.rs | 98 ++++++ demos/simple_demo/dependency-reduced-pom.xml | 44 +++ demos/simple_demo/pack/app.jar | Bin 0 -> 260150 bytes demos/simple_demo/pack/app.yml | 7 + demos/simple_demo/pom.xml | 61 ++++ .../src/main/java/test/Application.java | 13 + .../src/main/java/test/functions/Simple.java | 11 + middlewares/cluster_config.yml | 17 +- middlewares/waverless/3.add_func.py | 3 +- middlewares/waverless/waverless | 2 +- 27 files changed, 834 insertions(+), 193 deletions(-) create mode 100644 bencher/app_fn_entries.yaml delete mode 100644 bencher/bench.yaml create mode 100644 bencher/scripts/run_with_all_log.sh rename bencher/src/{ => _deperacated}/demo_img_resize.rs (100%) rename bencher/src/{ => _deperacated}/demo_parallel.rs (100%) rename bencher/src/{ => _deperacated}/demo_sequential.rs (100%) rename bencher/src/{ => _deperacated}/demo_word_count.rs (100%) create mode 100644 bencher/src/mode_bench.rs create mode 100644 bencher/src/mode_call_once.rs create mode 100644 bencher/src/mode_first_call.rs create mode 100644 bencher/src/mode_prepare.rs delete mode 100644 bencher/src/parse_app.rs create mode 100644 bencher/src/response.rs create mode 100644 bencher/src/test_call_once.rs create mode 100644 demos/simple_demo/dependency-reduced-pom.xml create mode 100644 demos/simple_demo/pack/app.jar create mode 100644 demos/simple_demo/pack/app.yml create mode 100644 demos/simple_demo/pom.xml create mode 100644 demos/simple_demo/src/main/java/test/Application.java create mode 100644 demos/simple_demo/src/main/java/test/functions/Simple.java diff --git a/bencher/Cargo.lock b/bencher/Cargo.lock index 292a616..618c7c6 100644 --- a/bencher/Cargo.lock +++ b/bencher/Cargo.lock @@ -189,6 +189,7 @@ dependencies = [ "base64 0.13.1", "clap", "enum_dispatch", + "futures", "goose", "image", "interprocess", diff --git a/bencher/Cargo.toml b/bencher/Cargo.toml index 922daed..e5826ce 100644 --- a/bencher/Cargo.toml +++ b/bencher/Cargo.toml @@ -7,19 +7,20 @@ edition = "2021" [dependencies] goose = "^0.16.4" -tokio = {version="1.1",features=["process"]} +tokio = { version = "1.1", features = ["process"] } clap = { version = "4.5.7", features = ["derive"] } image = "0.24.1" rand = "0.8.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +serde_yaml = "0.9" base64 = "0.13" rust-s3 = "0.34.0" lazy_static = "1.4.0" -reqwest = { version="0.12.5", features = ["json"]} +reqwest = { version = "0.12.5", features = ["json"] } async-trait = "0.1.74" enum_dispatch = "0.3.13" -serde_yaml = "0.9" interprocess = "2.2.0" tracing = "0.1.40" -tracing-subscriber = "0.3" \ No newline at end of file +tracing-subscriber = "0.3" +futures = "0.3.30" diff --git a/bencher/app_fn_entries.yaml b/bencher/app_fn_entries.yaml new file mode 100644 index 0000000..712ca44 --- /dev/null +++ b/bencher/app_fn_entries.yaml @@ -0,0 +1,95 @@ +simple_demo: + name: "Simple Demo" + description: "A simple demo function" + language: "java" + runtime: "java11" + handler: "test.functions.Simple" + memory: 256 + timeout: 30 + prepare_data: [] + prepare_scripts: [] + fns: + simple: + args: {} + +# img_resize: +# resize: +# prepare_data: "image_${reqid}.jpg" +# prepare_script: | +# from PIL import Image, ImageDraw +# import random + +# def generate_random_image(width, height, output_path): +# # 创建一个空白图像 +# image = Image.new('RGB', (width, height), 'white') +# draw = ImageDraw.Draw(image) + +# # 生成随机颜色的像素 +# for x in range(width): +# for y in range(height): +# r = random.randint(0, 255) +# g = random.randint(0, 255) +# b = random.randint(0, 255) +# draw.point((x, y), fill=(r, g, b)) + +# # 保存图像 +# image.save(output_path) +# print(f"Image saved to {output_path}") + +# # 指定图片的宽度和高度 +# width = 800 +# height = 600 +# output_path = 'random_image.png' + +# # 生成随机图片 +# generate_random_image(width, height, output_path) + +# args: +# image_s3_path: "image_${reqid}.jpg" +# target_width: 50 +# target_height: 50 + +# parallel_composition: +# parallel: +# args: +# loopTime: 10000000 +# parallelIndex: 100 +# sequential: +# args: +# loopTime: 10000000 + +# word_count: +# prepare_data: +# - large_text_file.txt +# prepare_scripts: +# - | +# import os + +# def generate_paragraph(): +# paragraph = """ +# In a far-off land, nestled among the mountains, lies a small village known for its unique culture and friendly inhabitants. Each spring, the villagers hold a grand festival to celebrate the arrival of the flowering season. Visitors from all corners gather to enjoy this beautiful moment. During the festival, people don traditional attire and dance joyfully, filling the village with laughter and cheer. +# """ +# return paragraph + +# def generate_large_text_file(file_path, target_size_gb): +# target_size_bytes = target_size_gb * 1024 * 1024 * 1024 +# paragraph = generate_paragraph() +# paragraph_length = len(paragraph.encode('utf-8')) + +# with open(file_path, 'w') as file: +# while os.path.getsize(file_path) < target_size_bytes: +# file.write(paragraph) + +# final_size = os.path.getsize(file_path) / (1024 * 1024 * 1024) +# print(f"Generated file size: {final_size:.2f} GB") + +# # 生成一个 1 GB 大小的文件 +# file_path = 'large_text_file.txt' +# target_size_gb = 1 +# generate_large_text_file(file_path, target_size_gb) + +# fns: +# split: +# args: +# text_s3_path: "random_words.txt" +# count: \ No newline at end of file diff --git a/bencher/bench.yaml b/bencher/bench.yaml deleted file mode 100644 index 8c46fa5..0000000 --- a/bencher/bench.yaml +++ /dev/null @@ -1,10 +0,0 @@ -img_resize: - resize: - -parallel_composition: - parallel: - sequential: - -word_count: - split_word: - diff --git a/bencher/scripts/run_with_all_log.sh b/bencher/scripts/run_with_all_log.sh new file mode 100644 index 0000000..c73efba --- /dev/null +++ b/bencher/scripts/run_with_all_log.sh @@ -0,0 +1,4 @@ +# run with following command: +# source scripts/run_with_all_log.sh + +export RUST_LOG=trace,debug \ No newline at end of file diff --git a/bencher/src/demo_img_resize.rs b/bencher/src/_deperacated/demo_img_resize.rs similarity index 100% rename from bencher/src/demo_img_resize.rs rename to bencher/src/_deperacated/demo_img_resize.rs diff --git a/bencher/src/demo_parallel.rs b/bencher/src/_deperacated/demo_parallel.rs similarity index 100% rename from bencher/src/demo_parallel.rs rename to bencher/src/_deperacated/demo_parallel.rs diff --git a/bencher/src/demo_sequential.rs b/bencher/src/_deperacated/demo_sequential.rs similarity index 100% rename from bencher/src/demo_sequential.rs rename to bencher/src/_deperacated/demo_sequential.rs diff --git a/bencher/src/demo_word_count.rs b/bencher/src/_deperacated/demo_word_count.rs similarity index 100% rename from bencher/src/demo_word_count.rs rename to bencher/src/_deperacated/demo_word_count.rs diff --git a/bencher/src/main.rs b/bencher/src/main.rs index 6f2ad5a..b0e0cdc 100644 --- a/bencher/src/main.rs +++ b/bencher/src/main.rs @@ -1,15 +1,16 @@ -mod demo_img_resize; -mod demo_parallel; -mod demo_sequential; -mod demo_word_count; mod metric; +mod mode_bench; +mod mode_call_once; +mod mode_first_call; +mod mode_prepare; mod parse; -mod parse_app; mod parse_platform; mod parse_test_mode; mod platform_ow; mod platform_wl; mod prometheus; +mod test_call_once; +// mod reponse; use async_trait::async_trait; @@ -17,7 +18,6 @@ use clap::Parser; use enum_dispatch::enum_dispatch; use goose::prelude::*; use parse::Cli; -use parse_app::App; use s3::creds::Credentials; use s3::Bucket; use s3::BucketConfiguration; @@ -30,62 +30,71 @@ use std::sync::mpsc; use std::time::Duration; use tokio::sync::oneshot; use tokio::sync::Mutex; +use tracing::Level; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; +use tracing_subscriber::Layer; -lazy_static::lazy_static! { - pub static ref BUCKET:Bucket={ - let(tx,rx)=mpsc::channel(); - tokio::spawn(async move{ - let bucket_name="serverless-bench"; - let region=Region::Custom { - region: "eu-central-1".to_owned(), - endpoint: "http://192.168.31.96:9009".to_owned(), - }; - let credentials= Credentials { - access_key: Some("minioadmin".to_owned()), - secret_key: Some("minioadmin123".to_owned()), - security_token: None, - session_token: None, - expiration: None, - }; - - let mut bucket=Bucket::new(bucket_name,region.clone(), credentials.clone()).unwrap().with_path_style(); - - let bucket_exist=match bucket.exists().await{ - Err(e)=>{ - tracing::warn!("test s3 is not started, automatically start it"); - // docker-compose up -d at ../middlewares/minio/ - process::Command::new("docker-compose") - .arg("up") - .arg("-d") - .current_dir(PathBuf::from("../middlewares/minio/")) - .output() - .expect("failed to start minio"); - tokio::time::sleep(Duration::from_secs(15)).await; - bucket.exists().await.unwrap() - } - Ok(ok)=>ok - }; - - if bucket_exist { - for b in bucket.list("".to_owned(),None).await.unwrap(){ - bucket.delete_object(b.name).await.unwrap(); - // bucket.delete().await.unwrap(); - } - }else{ - bucket = Bucket::create_with_path_style( - bucket_name, - region, - credentials, - BucketConfiguration::default(), - ) - .await.unwrap() - .bucket; +fn new_bucket() -> Bucket { + let (tx, rx) = mpsc::channel(); + tokio::spawn(async move { + let bucket_name = "serverless-bench"; + let region = Region::Custom { + region: "eu-central-1".to_owned(), + endpoint: "http://192.168.31.96:9009".to_owned(), + }; + let credentials = Credentials { + access_key: Some("minioadmin".to_owned()), + secret_key: Some("minioadmin123".to_owned()), + security_token: None, + session_token: None, + expiration: None, + }; + + let mut bucket = Bucket::new(bucket_name, region.clone(), credentials.clone()) + .unwrap() + .with_path_style(); + + let bucket_exist = match bucket.exists().await { + Err(e) => { + tracing::warn!("test s3 is not started, automatically start it"); + // docker-compose up -d at ../middlewares/minio/ + process::Command::new("docker-compose") + .arg("up") + .arg("-d") + .current_dir(PathBuf::from("../middlewares/minio/")) + .output() + .expect("failed to start minio"); + tokio::time::sleep(Duration::from_secs(15)).await; + bucket.exists().await.unwrap() } + Ok(ok) => ok, + }; - tx.send(bucket); - }); - rx.recv().unwrap() - }; + if bucket_exist { + for b in bucket.list("".to_owned(), None).await.unwrap() { + bucket.delete_object(b.name).await.unwrap(); + // bucket.delete().await.unwrap(); + } + } else { + bucket = Bucket::create_with_path_style( + bucket_name, + region, + credentials, + BucketConfiguration::default(), + ) + .await + .unwrap() + .bucket; + } + + tx.send(bucket); + }); + rx.recv().unwrap() +} + +lazy_static::lazy_static! { + pub static ref BUCKET:Bucket=new_bucket(); } fn is_bench_mode(cli: &Cli) -> bool { @@ -96,17 +105,20 @@ fn is_first_call_mode(cli: &Cli) -> bool { cli.first_call_mode > 0 } -fn is_once_mode(cli: &Cli) -> bool { - !is_bench_mode(cli) && !is_first_call_mode(cli) +fn is_prepare_mode(cli: &Cli) -> bool { + cli.prepare > 0 } -#[enum_dispatch(SpecTarget)] -enum SpecTargetBind { - ImgResize(demo_img_resize::ImgResize), - WordCount(demo_word_count::WordCount), - Parallel(demo_parallel::Parallel), - Sequential(demo_sequential::Sequential), +fn is_once_mode(cli: &Cli) -> bool { + !is_bench_mode(cli) && !is_first_call_mode(cli) } +// #[enum_dispatch(SpecTarget)] +// enum SpecTargetBind { +// ImgResize(demo_img_resize::ImgResize), +// WordCount(demo_word_count::WordCount), +// Parallel(demo_parallel::Parallel), +// Sequential(demo_sequential::Sequential), +// } /// unit: ms #[derive(Debug, Serialize, Deserialize, Clone)] @@ -152,29 +164,29 @@ impl Metric { } } -#[enum_dispatch] -trait SpecTarget: Send + 'static { - fn app(&self) -> App; - fn set_platform(&mut self, platform: PlatformOpsBind); - fn get_platform(&mut self) -> &mut PlatformOpsBind; +// #[enum_dispatch] +// trait SpecTarget: Send + 'static { +// fn app(&self) -> App; +// fn set_platform(&mut self, platform: PlatformOpsBind); +// fn get_platform(&mut self) -> &mut PlatformOpsBind; - async fn prepare_once(&mut self, _seed: String, _cli: Cli) { - unimplemented!() - } - async fn call_once(&mut self, _cli: Cli) -> Metric { - unimplemented!() - } - async fn prepare_bench(&mut self, _seed: String, _cli: Cli) {} - async fn call_bench(&mut self, _cli: Cli) { - unimplemented!() - } - async fn prepare_first_call(&mut self, _seed: String, _cli: Cli) { - unimplemented!() - } - async fn call_first_call(&mut self, _cli: Cli) { - unimplemented!() - } -} +// async fn prepare_once(&mut self, _seed: String, _cli: Cli) { +// unimplemented!() +// } +// async fn call_once(&mut self, _cli: Cli) -> Metric { +// unimplemented!() +// } +// async fn prepare_bench(&mut self, _seed: String, _cli: Cli) {} +// async fn call_bench(&mut self, _cli: Cli) { +// unimplemented!() +// } +// async fn prepare_first_call(&mut self, _seed: String, _cli: Cli) { +// unimplemented!() +// } +// async fn call_first_call(&mut self, _cli: Cli) { +// unimplemented!() +// } +// } #[enum_dispatch(PlatformOps)] enum PlatformOpsBind { @@ -193,60 +205,94 @@ pub trait PlatformOps: Send + 'static { // err: String, // } +pub fn start_tracing() { + let my_filter = tracing_subscriber::filter::filter_fn(|v| { + // println!("{}", v.module_path().unwrap()); + // println!("{}", v.name()); + // if v.module_path().unwrap().contains("quinn_proto") { + // return false; + // } + + // if v.module_path().unwrap().contains("qp2p::wire_msg") { + // return false; + // } + + // println!("{}", v.target()); + if let Some(mp) = v.module_path() { + if mp.contains("async_raft") { + return false; + } + if mp.contains("hyper") { + return false; + } + } + + // if v.module_path().unwrap().contains("less::network::p2p") { + // return false; + // } + + // v.level() == &tracing::Level::ERROR + // || v.level() == &tracing::Level::WARN + // || v.level() == &tracing::Level::INFO + v.level() != &tracing::Level::TRACE + // v.level() == &tracing::Level::INFO + // true + }); + let my_layer = tracing_subscriber::fmt::layer(); + tracing_subscriber::registry() + .with(my_layer.with_filter(my_filter)) + .init(); +} + #[tokio::main] async fn main() -> Result<(), GooseError> { // don't go thouph proxy when performance std::env::remove_var("http_proxy"); std::env::remove_var("https_proxy"); - let subscriber = tracing_subscriber::FmtSubscriber::new(); - tracing::subscriber::set_global_default(subscriber).unwrap(); + + start_tracing(); let cli = Cli::parse(); - let seed = "helloworld"; + cli.check_app_fn().check_platform().check_mode(); - assert!( - !(cli.with_ow > 0 && cli.with_wl > 0), - "Cannot run with both OpenWhisk and Waverless" - ); - - assert!( - cli.bench_mode + cli.first_call_mode <= 1, - "Cannot test multiple modes at one time {}", - cli.bench_mode + cli.first_call_mode - ); - - let mut target = if cli.img_resize > 0 { - SpecTargetBind::from(demo_img_resize::ImgResize::default()) - } else if cli.word_count > 0 { - SpecTargetBind::from(demo_word_count::WordCount::default()) - } else if cli.parallel > 0 { - SpecTargetBind::from(demo_parallel::Parallel::default()) - } else if cli.sequential > 0 { - SpecTargetBind::from(demo_sequential::Sequential::default()) - } else { - unreachable!() - }; - target.set_platform(if cli.with_ow > 0 { + let seed = "helloworld"; + tracing::debug!("Preparing paltform >>>"); + let mut platform = if cli.with_ow > 0 { PlatformOpsBind::from(platform_ow::PlatfromOw::default()) } else if cli.with_wl > 0 { PlatformOpsBind::from(platform_wl::PlatfromWl::new()) } else { - panic!(); - }); + panic!("no platform specified, please specify by --with-ow or --with-wl"); + }; + tracing::debug!("dispatching mode >>>"); + fn print_mode(mode: &str, preparing: bool) { + tracing::debug!("==========================="); + tracing::debug!("Current mode is {mode}"); + tracing::debug!("Preparing: {preparing}"); + tracing::debug!("==========================="); + } if is_bench_mode(&cli) { - target.prepare_bench(seed.to_owned(), cli.clone()).await; - target.call_bench(cli).await; + print_mode("bench", is_bench_mode(&cli)); + unimplemented!(); + // target.prepare_bench(seed.to_owned(), cli.clone()).await; + // target.call_bench(cli).await; } else if is_first_call_mode(&cli) { - target - .prepare_first_call(seed.to_owned(), cli.clone()) - .await; - target.call_first_call(cli).await; + print_mode("first_call", is_bench_mode(&cli)); + if is_prepare_mode(&cli) { + mode_first_call::prepare(&mut platform, seed.to_owned(), cli.clone()).await; + } else { + mode_first_call::call(&mut platform, cli).await; + } } else if is_once_mode(&cli) { - target.prepare_once(seed.to_owned(), cli.clone()).await; - // wait for the system to be stable - tokio::time::sleep(Duration::from_secs(5)).await; - target.call_once(cli).await; + print_mode("first_call", is_bench_mode(&cli)); + if is_prepare_mode(&cli) { + mode_call_once::prepare(&mut platform, seed.to_owned(), cli.clone()).await; + } else { + mode_call_once::call(&mut platform, cli).await; + } + } else { + panic!("unreachable") } Ok(()) diff --git a/bencher/src/mode_bench.rs b/bencher/src/mode_bench.rs new file mode 100644 index 0000000..13cb390 --- /dev/null +++ b/bencher/src/mode_bench.rs @@ -0,0 +1,3 @@ +pub fn call_bench() { + unimplemented!(); +} diff --git a/bencher/src/mode_call_once.rs b/bencher/src/mode_call_once.rs new file mode 100644 index 0000000..cd9df4a --- /dev/null +++ b/bencher/src/mode_call_once.rs @@ -0,0 +1,120 @@ +use std::{ + collections::HashMap, + fs, + time::{SystemTime, UNIX_EPOCH}, +}; + +use clap::Args; +use serde_yaml::Value; + +use crate::{parse::Cli, Metric, PlatformOps, PlatformOpsBind, BUCKET}; + +pub async fn prepare(platform: &mut PlatformOpsBind, seed: String, cli: Cli) { + platform.remove_all_fn().await; + platform.upload_fn("simple_demo", "").await; + // self.prepare_img(&seed); +} + +pub async fn call(platform: &mut PlatformOpsBind, cli: Cli) -> Metric { + // read image from file + // let img = fs::read("img_resize/image_0.jpg").unwrap(); + + // BUCKET + // // .lock() + // // .await + // .put_object(format!("image_{}.jpg", 0), &img) + // .await + // .unwrap(); + + let args = cli.func_details().args; + // let arg = Args { + // image_s3_path: format!("image_{}.jpg", 0), + // target_width: 50, + // target_height: 50, + // }; + + let start_call_ms = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_millis() as u64; + // let output = platform + // .call_fn("img_resize", "resize", &serde_json::to_value(args).unwrap()) + // .await; + let output = platform + .call_fn("simple_demo", "simple", &serde_json::to_value(args).unwrap()) + .await; + // tracing::info!("debug output {}", output); + let res: serde_json::Value = serde_json::from_str(&output).unwrap_or_else(|e| { + tracing::error!("failed to parse json: {}", e); + panic!("output is not json: '{}'", output); + }); + + let mut req_arrive_time = res + .get("req_arrive_time") + .map(|v| v.as_u64().unwrap()) + .unwrap_or(0); + + let mut bf_exec_time = res + .get("bf_exec_time") + .map(|v| v.as_u64().unwrap()) + .unwrap_or(0); + + let mut recover_begin_time = res + .get("recover_begin_time") + .map(|v| v.as_u64().unwrap()) + .unwrap_or(0); + + let fn_start_ms = res.get("fn_start_time").unwrap().as_u64().unwrap(); + { + if req_arrive_time == 0 { + req_arrive_time = fn_start_ms; + } + if bf_exec_time == 0 { + bf_exec_time = fn_start_ms; + } + if recover_begin_time == 0 { + recover_begin_time = fn_start_ms; + } + } + + let fn_end_ms = res.get("fn_end_time").unwrap().as_u64().unwrap(); + + let receive_resp_time = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_millis() as u64; + + println!("debug output: {:?}", output); + println!( + "\ntotal request latency: {}", + receive_resp_time - start_call_ms + ); + + println!("- req trans time: {}", req_arrive_time - start_call_ms); + println!("- app verify time: {}", bf_exec_time - req_arrive_time); + println!("- cold start time: {}", recover_begin_time - bf_exec_time); + println!("- cold start time2: {}", fn_start_ms - recover_begin_time); + println!("- exec time:{}", fn_end_ms - fn_start_ms); + if fn_end_ms > receive_resp_time { + println!( + "- system time is not synced, lag with {} ms", + fn_end_ms - receive_resp_time + ); + } else { + println!("- receive resp time: {}", receive_resp_time - fn_end_ms); + } + + // let res: Resp = serde_json::from_str(&output).expect("Failed to parse JSON response"); + // let res = BUCKET.get_object(&res.resized_image).await.unwrap(); + // std::fs::write("resized_image.jpg", res.as_slice()).unwrap(); + + Metric { + start_call_time: start_call_ms, + req_arrive_time, + bf_exec_time, + recover_begin_time, + fn_start_time: fn_start_ms, + fn_end_time: fn_end_ms, + receive_resp_time, + } +} diff --git a/bencher/src/mode_first_call.rs b/bencher/src/mode_first_call.rs new file mode 100644 index 0000000..872fe13 --- /dev/null +++ b/bencher/src/mode_first_call.rs @@ -0,0 +1,65 @@ +use crate::{ + metric::Recorder, mode_call_once, parse::Cli, parse_platform::Platform, + parse_test_mode::TestMode, PlatformOps, PlatformOpsBind, +}; + +pub async fn prepare(platform: &mut PlatformOpsBind, seed: String, cli: Cli) { + platform.remove_all_fn().await; + // cli.prepare_img(&seed); +} + +pub async fn call(platform: &mut PlatformOpsBind, cli: Cli) { + let app = cli.app().expect("first call mode must have app name"); + let func = cli.func().expect("first call mode must have func name"); + + let mut recorder = Recorder::new(app.to_string(), TestMode::from(&cli), Platform::from(&cli)); + + let mut metrics = vec![]; + for _ in 0..20 { + platform.upload_fn("simple_demo", "").await; + let m = mode_call_once::call(platform, cli.clone()).await; //self.call_once(cli.clone()).await; + recorder.record(m.clone()); + // prometheus::upload_fn_call_metric("simple_demo", &m).await; + metrics.push(m); + } + recorder.persist(); + + println!("Average metrics:"); + println!( + "\ntotal request latency: {}", + metrics.iter().map(|v| v.get_total_req()).sum::() as f32 / metrics.len() as f32 + ); + + println!( + "- req trans time: {}", + metrics.iter().map(|v| v.get_req_trans_time()).sum::() as f32 / metrics.len() as f32 + ); + + println!( + "- app verify time: {}", + metrics.iter().map(|v| v.get_app_verify_time()).sum::() as f32 / metrics.len() as f32 + ); + + println!( + "- cold start time: {}", + metrics.iter().map(|v| v.get_cold_start_time()).sum::() as f32 / metrics.len() as f32 + ); + + println!( + "- cold start time2: {}", + metrics + .iter() + .map(|v| v.get_cold_start_time2()) + .sum::() as f32 + / metrics.len() as f32 + ); + + println!( + "- exec time: {}", + metrics.iter().map(|v| v.get_exec_time()).sum::() as f32 / metrics.len() as f32 + ); + // println!("- app verify time: {}", bf_exec_time - req_arrive_time); + // println!("- cold start time: {}", recover_begin_time - bf_exec_time); + // println!("- cold start time2: {}", fn_start_ms - recover_begin_time); + // println!("- exec time:{}", fn_end_ms - fn_start_ms); +} diff --git a/bencher/src/mode_prepare.rs b/bencher/src/mode_prepare.rs new file mode 100644 index 0000000..db96dd3 --- /dev/null +++ b/bencher/src/mode_prepare.rs @@ -0,0 +1,5 @@ +use crate::parse::Cli; + +fn prepare(cli:Cli){ + +} \ No newline at end of file diff --git a/bencher/src/parse.rs b/bencher/src/parse.rs index 2502db3..a413a80 100644 --- a/bencher/src/parse.rs +++ b/bencher/src/parse.rs @@ -1,23 +1,22 @@ +use core::panic; +use std::collections::HashMap; +use std::fs::File; +use std::io::BufReader; + use clap::arg; use clap::value_parser; use clap::{command, Command}; use clap::{Parser, Subcommand}; +use serde_yaml::Value; #[derive(Parser, Clone)] #[command(version, about, long_about = None)] pub struct Cli { // #[arg(action = clap::ArgAction::Count)] - #[arg(long, action = clap::ArgAction::Count)] - pub img_resize: u8, + pub app_fn: String, #[arg(long, action = clap::ArgAction::Count)] - pub word_count: u8, - - #[arg(long, action = clap::ArgAction::Count)] - pub parallel: u8, - - #[arg(long, action = clap::ArgAction::Count)] - pub sequential: u8, + pub prepare: u8, #[arg(long, action = clap::ArgAction::Count)] pub with_ow: u8, @@ -32,3 +31,103 @@ pub struct Cli { #[arg(long, action = clap::ArgAction::Count)] pub first_call_mode: u8, } + +#[derive(serde::Deserialize, Debug, Clone)] +pub struct FnDetails { + pub args: Option>, +} + +#[derive(serde::Deserialize, Debug)] +pub struct AppFnEntry { + pub prepare_data: Vec, + pub prepare_scripts: Vec, + pub fns: HashMap, +} +// app: +// prepare_data: +// - file1 +// prepare_scripts: +// - script1 +// fns: +// fn1: +// args: +pub type AppFnEntries = HashMap; + +impl Cli { + pub fn app(&self) -> Option { + if self.app_fn.find("/").is_none() { + return None; + } + return Some(self.app_fn.split("/").next().unwrap().to_owned()); + } + pub fn func(&self) -> Option { + if self.app_fn.find("/").is_none() { + return None; + } + let mut iter = self.app_fn.split("/"); + iter.next(); + return Some(iter.next().unwrap().to_owned()); + } + pub fn func_details(&self) -> FnDetails { + let app = self.app().unwrap_or_else(|| { + panic!("missing app name, cur input is {}", self.app_fn); + }); + let func = self.func().unwrap_or_else(|| { + panic!("missing fn name, cur input is {}", self.app_fn); + }); + + //read 'app_fn_entries.yaml' + let f = File::open("app_fn_entries.yaml").expect("open app_fn_entries.yaml failed"); + let freader = BufReader::new(f); + let app_fn_entries: AppFnEntries = serde_yaml::from_reader(freader).unwrap_or_else(|e| { + panic!("parse 'app_fn_entries.yaml' failed with {:?}", e); + }); + + let f = app_fn_entries + .get(&app) + .unwrap_or_else(|| panic!("app '{}' is not in app_fn_entries.yaml", app)) + .fns + .get(&func) + .unwrap_or_else(|| panic!("function '{}' is not in app '{}' in app_fn_entries.yaml", func, app)); + f.clone() + } + pub fn check_app_fn(&self) -> &Self { + let app = self.app().unwrap_or_else(|| { + panic!("missing app name, cur input is {}", self.app_fn); + }); + let func = self.func().unwrap_or_else(|| { + panic!("missing fn name, cur input is {}", self.app_fn); + }); + + //read 'app_fn_entries.yaml' + let f = File::open("app_fn_entries.yaml").expect("open app_fn_entries.yaml failed"); + let freader = BufReader::new(f); + let app_fn_entries: AppFnEntries = serde_yaml::from_reader(freader).unwrap_or_else(|e| { + panic!("parse 'app_fn_entries.yaml' failed with {:?}", e); + }); + + let _ = app_fn_entries + .get(&app) + .unwrap_or_else(|| panic!("app '{}' is not in app_fn_entries.yaml", app)) + .fns + .get(&func) + .unwrap_or_else(|| panic!("function '{}' is not in app '{}' in app_fn_entries.yaml", func, app)); + self + } + pub fn check_platform(&self) -> &Self { + assert!( + !(self.with_ow > 0 && self.with_wl > 0), + "Cannot run with both OpenWhisk and Waverless" + ); + self + } + + pub fn check_mode(&self) -> &Self { + assert!( + self.bench_mode + self.first_call_mode <= 1, + "Cannot test multiple modes at one time {}", + self.bench_mode + self.first_call_mode + ); + self + } +} diff --git a/bencher/src/parse_app.rs b/bencher/src/parse_app.rs deleted file mode 100644 index 227bd2a..0000000 --- a/bencher/src/parse_app.rs +++ /dev/null @@ -1,35 +0,0 @@ -use crate::parse::Cli; - -pub enum App { - ImgResize, - WordCount, - Parallel, - Sequential, -} - -impl From<&Cli> for App { - fn from(cli: &Cli) -> Self { - if cli.img_resize > 0 { - App::ImgResize - } else if cli.word_count > 0 { - App::WordCount - } else if cli.parallel > 0 { - App::Parallel - } else if cli.sequential > 0 { - App::Sequential - } else { - unimplemented!() - } - } -} - -impl ToString for App { - fn to_string(&self) -> String { - match self { - App::ImgResize => "img_resize".to_owned(), - App::WordCount => "word_count".to_owned(), - App::Parallel => "parallel".to_owned(), - App::Sequential => "sequential".to_owned(), - } - } -} diff --git a/bencher/src/response.rs b/bencher/src/response.rs new file mode 100644 index 0000000..d0a5cca --- /dev/null +++ b/bencher/src/response.rs @@ -0,0 +1,7 @@ +use std::collections::HashMap; + +use serde_yaml::Value; + +pub type Resp = HashMap; + +pub trait RespMetricExt {} diff --git a/bencher/src/test_call_once.rs b/bencher/src/test_call_once.rs new file mode 100644 index 0000000..1f3ad72 --- /dev/null +++ b/bencher/src/test_call_once.rs @@ -0,0 +1,98 @@ +use std::{ + collections::HashMap, + fs, + time::{SystemTime, UNIX_EPOCH}, +}; + +use clap::Args; +use serde_yaml::Value; + +use crate::{parse::Cli, Metric, PlatformOps, PlatformOpsBind, BUCKET}; + +pub async fn prepare(platform: &mut PlatformOpsBind, seed: String, cli: Cli) { + platform.remove_all_fn().await; + platform.upload_fn("simple_demo", "/root/ygy/demos/simple_demo/pack").await; +} + +pub async fn call(platform: &mut PlatformOpsBind, cli: Cli) -> Metric { + let args = cli.func_details().args.unwrap_or_default(); + + let start_call_ms = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_millis() as u64; + + let output = platform + .call_fn("simple_demo", "simple", &serde_json::to_value(args).unwrap()) + .await; + + let res: serde_json::Value = serde_json::from_str(&output).unwrap_or_else(|e| { + tracing::error!("failed to parse json: {}", e); + panic!("output is not json: '{}'", output); + }); + + let mut req_arrive_time = res + .get("req_arrive_time") + .map(|v| v.as_u64().unwrap()) + .unwrap_or(0); + + let mut bf_exec_time = res + .get("bf_exec_time") + .map(|v| v.as_u64().unwrap()) + .unwrap_or(0); + + let mut recover_begin_time = res + .get("recover_begin_time") + .map(|v| v.as_u64().unwrap()) + .unwrap_or(0); + + let fn_start_ms = res.get("fn_start_time").unwrap().as_u64().unwrap(); + { + if req_arrive_time == 0 { + req_arrive_time = fn_start_ms; + } + if bf_exec_time == 0 { + bf_exec_time = fn_start_ms; + } + if recover_begin_time == 0 { + recover_begin_time = fn_start_ms; + } + } + + let fn_end_ms = res.get("fn_end_time").unwrap().as_u64().unwrap(); + + let receive_resp_time = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_millis() as u64; + + println!("debug output: {:?}", output); + println!( + "\ntotal request latency: {}", + receive_resp_time - start_call_ms + ); + + println!("- req trans time: {}", req_arrive_time - start_call_ms); + println!("- app verify time: {}", bf_exec_time - req_arrive_time); + println!("- cold start time: {}", recover_begin_time - bf_exec_time); + println!("- cold start time2: {}", fn_start_ms - recover_begin_time); + println!("- exec time:{}", fn_end_ms - fn_start_ms); + if fn_end_ms > receive_resp_time { + println!( + "- system time is not synced, lag with {} ms", + fn_end_ms - receive_resp_time + ); + } else { + println!("- receive resp time: {}", receive_resp_time - fn_end_ms); + } + + Metric { + start_call_time: start_call_ms, + req_arrive_time, + bf_exec_time, + recover_begin_time, + fn_start_time: fn_start_ms, + fn_end_time: fn_end_ms, + receive_resp_time, + } +} diff --git a/demos/simple_demo/dependency-reduced-pom.xml b/demos/simple_demo/dependency-reduced-pom.xml new file mode 100644 index 0000000..2dfebc8 --- /dev/null +++ b/demos/simple_demo/dependency-reduced-pom.xml @@ -0,0 +1,44 @@ + + + 4.0.0 + test + simple-demo + 1.0-SNAPSHOT + + + + maven-compiler-plugin + 3.8.1 + + 11 + 11 + + + + maven-shade-plugin + 3.4.1 + + + package + + shade + + + simple_demo-1.0-SNAPSHOT-jar-with-dependencies + + + test.Application + + + + + + + + + + 11 + 11 + UTF-8 + + diff --git a/demos/simple_demo/pack/app.jar b/demos/simple_demo/pack/app.jar new file mode 100644 index 0000000000000000000000000000000000000000..9f80c25dd476be27a06e49ebf2b716c42eeeaeed GIT binary patch literal 260150 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 E0me7dF#rGn literal 0 HcmV?d00001 diff --git a/demos/simple_demo/pack/app.yml b/demos/simple_demo/pack/app.yml new file mode 100644 index 0000000..ee4f437 --- /dev/null +++ b/demos/simple_demo/pack/app.yml @@ -0,0 +1,7 @@ +name: simple_demo +version: 1.0.0 +functions: + - name: simple + handler: test.functions.Simple + memory: 128 + timeout: 30 \ No newline at end of file diff --git a/demos/simple_demo/pom.xml b/demos/simple_demo/pom.xml new file mode 100644 index 0000000..25b724e --- /dev/null +++ b/demos/simple_demo/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + test + simple-demo + 1.0-SNAPSHOT + + + 11 + 11 + UTF-8 + + + + + com.google.code.gson + gson + 2.8.9 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 11 + 11 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.4.1 + + + package + + shade + + + simple_demo-1.0-SNAPSHOT-jar-with-dependencies + + + test.Application + + + + + + + + + + \ No newline at end of file diff --git a/demos/simple_demo/src/main/java/test/Application.java b/demos/simple_demo/src/main/java/test/Application.java new file mode 100644 index 0000000..48a8c35 --- /dev/null +++ b/demos/simple_demo/src/main/java/test/Application.java @@ -0,0 +1,13 @@ +package test; + +import com.google.gson.JsonObject; +import test.functions.Simple; + +public class Application { + public static void main(String[] args) { + Simple simple = new Simple(); + JsonObject input = new JsonObject(); + JsonObject result = simple.call(input); + System.out.println(result.toString()); + } +} \ No newline at end of file diff --git a/demos/simple_demo/src/main/java/test/functions/Simple.java b/demos/simple_demo/src/main/java/test/functions/Simple.java new file mode 100644 index 0000000..3518158 --- /dev/null +++ b/demos/simple_demo/src/main/java/test/functions/Simple.java @@ -0,0 +1,11 @@ +package test.functions; + +import com.google.gson.JsonObject; + +public class Simple { + public JsonObject call(JsonObject input) { + JsonObject result = new JsonObject(); + result.addProperty("message", "Hello from Simple function!"); + return result; + } +} \ No newline at end of file diff --git a/middlewares/cluster_config.yml b/middlewares/cluster_config.yml index 542822f..d9f5853 100644 --- a/middlewares/cluster_config.yml +++ b/middlewares/cluster_config.yml @@ -4,14 +4,14 @@ # lab2: # ip: 192.168.31.87 -lab3: - ip: 192.168.31.96 - is_master: +# lab3: +# ip: 192.168.31.96 +# is_master: # lab7: # ip: 192.168.31.89 -lab8: - ip: 192.168.31.54 +# lab8: +# ip: 192.168.31.54 # lab9: # ip: 192.168.31.9 # is_master: @@ -20,4 +20,9 @@ lab8: # lab11: # ip: 192.168.31.138 # lab12: -# ip: 192.168.31.171 \ No newline at end of file +# ip: 192.168.31.171 +master: + ip: 127.0.0.1 + is_master: +worker: + ip: 127.0.0.1 \ No newline at end of file diff --git a/middlewares/waverless/3.add_func.py b/middlewares/waverless/3.add_func.py index 044b15f..7143a22 100644 --- a/middlewares/waverless/3.add_func.py +++ b/middlewares/waverless/3.add_func.py @@ -55,7 +55,8 @@ def run_cmd_with_res(cmd): # pylib.os_system_sure(f"python3 scripts/1.gen_waverless_app.py {demo_app}") def upload_app(appname,rename): appdir=f"scripts/waverless/{appname}/pack" - + # 复制 JAR 文件到应用包 + os.system(f"cp ../demos/{appname}/target/{appname}-1.0-SNAPSHOT-jar-with-dependencies.jar {appdir}/app.jar") os.chdir(appdir) diff --git a/middlewares/waverless/waverless b/middlewares/waverless/waverless index 39e6ad6..030b670 160000 --- a/middlewares/waverless/waverless +++ b/middlewares/waverless/waverless @@ -1 +1 @@ -Subproject commit 39e6ad6a144db58b0a457f30f2fc027e051e0d8f +Subproject commit 030b6702072632beb35da63db1c3d4cdf3faf2f3 From e50ba030baada27b93ba0b87e83f5754984468f2 Mon Sep 17 00:00:00 2001 From: ActivePeter <1020401660@qq.com> Date: Wed, 7 May 2025 16:20:17 +0800 Subject: [PATCH 3/4] zip_dir_2_file --- middlewares/waverless/waverless | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middlewares/waverless/waverless b/middlewares/waverless/waverless index 030b670..11469fe 160000 --- a/middlewares/waverless/waverless +++ b/middlewares/waverless/waverless @@ -1 +1 @@ -Subproject commit 030b6702072632beb35da63db1c3d4cdf3faf2f3 +Subproject commit 11469fe17f28fe4fe763a61bdf74ba9f161bdabf From a55cc58f5300857527fd193856b1c56855104412 Mon Sep 17 00:00:00 2001 From: ActivePeter <1020401660@qq.com> Date: Tue, 13 May 2025 18:56:14 +0800 Subject: [PATCH 4/4] data api java app waverless inner data storage --- bencher/.gitignore | 1 + bencher/app_fn_entries.yaml | 197 ++++++++++------- bencher/src/_deperacated/demo_word_count.rs | 18 +- bencher/src/common_prepare.rs | 74 +++++++ bencher/src/config.rs | 104 +++++++++ bencher/src/main.rs | 105 ++++----- bencher/src/minio.rs | 84 ++++++++ bencher/src/mode_call_once.rs | 45 +++- bencher/src/mode_first_call.rs | 9 +- bencher/src/parse.rs | 88 ++++---- bencher/src/platform_ow.rs | 42 +++- bencher/src/platform_wl.rs | 62 ++++-- bencher/src/test_call_once.rs | 19 +- bencher/src/util.rs | 52 +++++ demos/_java_serverless_lib/core/pom.xml | 5 + .../java/io/serverless_lib/BeanConfig.java | 5 + .../main/java/io/serverless_lib/DataApi.java | 202 ++++++++++++++++++ .../java/io/serverless_lib/UdsBackend.java | 1 + .../scripts/prepare_protoc.py | 2 +- .../src/main/java/test/functions/Resize.java | 60 ++++-- middlewares/1.firsttime_deploy_waverless.py | 2 +- middlewares/2.update_waverless_bin.py | 4 +- middlewares/cluster_config.yml | 28 +-- middlewares/waverless/3.add_func.py | 49 +++-- 24 files changed, 969 insertions(+), 289 deletions(-) create mode 100644 bencher/.gitignore create mode 100644 bencher/src/common_prepare.rs create mode 100644 bencher/src/config.rs create mode 100644 bencher/src/minio.rs create mode 100644 bencher/src/util.rs create mode 100644 demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/DataApi.java diff --git a/bencher/.gitignore b/bencher/.gitignore new file mode 100644 index 0000000..3f197ab --- /dev/null +++ b/bencher/.gitignore @@ -0,0 +1 @@ +prepare_data \ No newline at end of file diff --git a/bencher/app_fn_entries.yaml b/bencher/app_fn_entries.yaml index 712ca44..3fa03e9 100644 --- a/bencher/app_fn_entries.yaml +++ b/bencher/app_fn_entries.yaml @@ -1,53 +1,120 @@ -simple_demo: - name: "Simple Demo" - description: "A simple demo function" - language: "java" - runtime: "java11" - handler: "test.functions.Simple" - memory: 256 - timeout: 30 - prepare_data: [] - prepare_scripts: [] - fns: - simple: - args: {} - -# img_resize: -# resize: -# prepare_data: "image_${reqid}.jpg" -# prepare_script: | -# from PIL import Image, ImageDraw -# import random - -# def generate_random_image(width, height, output_path): -# # 创建一个空白图像 -# image = Image.new('RGB', (width, height), 'white') -# draw = ImageDraw.Draw(image) - -# # 生成随机颜色的像素 -# for x in range(width): -# for y in range(height): -# r = random.randint(0, 255) -# g = random.randint(0, 255) -# b = random.randint(0, 255) -# draw.point((x, y), fill=(r, g, b)) - -# # 保存图像 -# image.save(output_path) -# print(f"Image saved to {output_path}") - -# # 指定图片的宽度和高度 -# width = 800 -# height = 600 -# output_path = 'random_image.png' - -# # 生成随机图片 -# generate_random_image(width, height, output_path) - -# args: -# image_s3_path: "image_${reqid}.jpg" -# target_width: 50 -# target_height: 50 +minio: + endpoint: "http://192.168.31.54:9009" + access_key: "minioadmin" + secret_key: "minioadmin123" + compose_path: "../middlewares/minio/" + +models: + simple_demo: + # name: "Simple Demo" + # description: "A simple demo function" + # language: "java" + # runtime: "java11" + # handler: "test.functions.Simple" + # memory: 256 + # timeout: 30 + prepare_data: [] + prepare_scripts: [] + fns: + simple: + args: {} + + img_resize: + fns: + resize: + args: + use_minio: true + image_s3_path: "image_to_resize.png" + target_width: 50 + target_height: 50 + prepare_data: ["image_to_resize.png"] + prepare_scripts: + - | + from PIL import Image, ImageDraw + import random + + def generate_random_image(width, height, output_path): + # 创建一个空白图像 + image = Image.new('RGB', (width, height), 'white') + draw = ImageDraw.Draw(image) + + # 生成随机颜色的像素 + for x in range(width): + for y in range(height): + r = random.randint(0, 255) + g = random.randint(0, 255) + b = random.randint(0, 255) + draw.point((x, y), fill=(r, g, b)) + + # 保存图像 + image.save(output_path) + print(f"Image saved to {output_path}") + + # 指定图片的宽度和高度 + width = 800 + height = 600 + output_path = 'image_to_resize.png' + + # 生成随机图片 + generate_random_image(width, height, output_path) + + word_count: + prepare_data: + - large_text_file.txt + prepare_scripts: + - | + import os + + def generate_paragraph(): + paragraph = """ + In a far-off land, nestled among the mountains, lies a small village known for its unique culture and friendly inhabitants. Each spring, the villagers hold a grand festival to celebrate the arrival of the flowering season. Visitors from all corners gather to enjoy this beautiful moment. During the festival, people don traditional attire and dance joyfully, filling the village with laughter and cheer. + """ + return paragraph + + def generate_large_text_file(file_path, target_size_gb): + target_size_bytes = target_size_gb * 1024 * 1024 * 1024 + paragraph = generate_paragraph() + paragraph_length = len(paragraph.encode('utf-8')) + + with open(file_path, 'w') as file: + while os.path.getsize(file_path) < target_size_bytes: + file.write(paragraph) + + final_size = os.path.getsize(file_path) / (1024 * 1024 * 1024) + print(f"Generated file size: {final_size:.2f} GB") + + # 生成一个 1 GB 大小的文件 + file_path = 'large_text_file.txt' + target_size_gb = 1 + generate_large_text_file(file_path, target_size_gb) + fns: + count: + args: + text_s3_path: "large_text_file.txt" + +# 函数配置项变体 +replicas: {} +benchlist: {} +# img_resize2: # 函数 和 是否使用minio排列组合,每种两个 +# source: img_resize + +# img_resize3: +# source: img_resize +# args: +# use_minio: false +# img_resize4: +# source: img_resize +# args: +# use_minio: false + + + +# benchlist: +# img_resize: +# img_resize2: +# img_resize3: +# img_resize4: + # parallel_composition: # parallel: @@ -58,35 +125,7 @@ simple_demo: # args: # loopTime: 10000000 -# word_count: -# prepare_data: -# - large_text_file.txt -# prepare_scripts: -# - | -# import os - -# def generate_paragraph(): -# paragraph = """ -# In a far-off land, nestled among the mountains, lies a small village known for its unique culture and friendly inhabitants. Each spring, the villagers hold a grand festival to celebrate the arrival of the flowering season. Visitors from all corners gather to enjoy this beautiful moment. During the festival, people don traditional attire and dance joyfully, filling the village with laughter and cheer. -# """ -# return paragraph - -# def generate_large_text_file(file_path, target_size_gb): -# target_size_bytes = target_size_gb * 1024 * 1024 * 1024 -# paragraph = generate_paragraph() -# paragraph_length = len(paragraph.encode('utf-8')) - -# with open(file_path, 'w') as file: -# while os.path.getsize(file_path) < target_size_bytes: -# file.write(paragraph) - -# final_size = os.path.getsize(file_path) / (1024 * 1024 * 1024) -# print(f"Generated file size: {final_size:.2f} GB") - -# # 生成一个 1 GB 大小的文件 -# file_path = 'large_text_file.txt' -# target_size_gb = 1 -# generate_large_text_file(file_path, target_size_gb) + # fns: # split: diff --git a/bencher/src/_deperacated/demo_word_count.rs b/bencher/src/_deperacated/demo_word_count.rs index f3d3ff7..72f7f03 100644 --- a/bencher/src/_deperacated/demo_word_count.rs +++ b/bencher/src/_deperacated/demo_word_count.rs @@ -97,10 +97,24 @@ impl SpecTarget for WordCount { receive_resp_time - start_call_ms ); + // | cold start time + // | + // | fn_start_ms + println!("- req trans time: {}", req_arrive_time - start_call_ms); println!("- app verify time: {}", bf_exec_time - req_arrive_time); - println!("- cold start time: {}", recover_begin_time - bf_exec_time); - println!("- cold start time2: {}", fn_start_ms - recover_begin_time); + println!( + "- cold start time: {}", + if bf_exec_time > recover_begin_time { + recover_begin_time - bf_exec_time + } else { + 0 + } + ); + println!( + "- cold start time2: {}", + fn_start_ms - recover_begin_time.max(req_arrive_time) + ); println!("- exec time:{}", fn_end_ms - fn_start_ms); if fn_end_ms > receive_resp_time { println!( diff --git a/bencher/src/common_prepare.rs b/bencher/src/common_prepare.rs new file mode 100644 index 0000000..b004199 --- /dev/null +++ b/bencher/src/common_prepare.rs @@ -0,0 +1,74 @@ +use std::{collections::HashMap, path::PathBuf, process::Stdio}; + +use tokio::{fs, process::Command}; + +use crate::config::Config; + +/// return each app datas +/// app->[data1,data2] +pub async fn prepare_data( + target_apps: Vec, + config: &Config, +) -> HashMap> { + let mut prepare_data = HashMap::new(); + let model_apps: Vec = target_apps + .clone() + .into_iter() + .filter(|app| config.models.contains_key(app)) + .collect(); + + for app in model_apps { + fs::create_dir_all(PathBuf::from("prepare_data").join(&app)) + .await + .unwrap(); + let app_entry = config.models.get(&app).unwrap(); + for (i, script) in app_entry.prepare_scripts.iter().enumerate() { + let script_path = PathBuf::from("prepare_data") + .join(&app) + .join(format!("prepare_{}.py", i)); + let script_dir = PathBuf::from("prepare_data").join(&app); + let abs_script_dir = script_dir.canonicalize().unwrap(); + // let abs_script_path = script_path.canonicalize().unwrap(); + fs::write(&script_path, script).await.unwrap(); + + tracing::debug!( + "prepare data for {} with script {}", + app, + script_path.to_str().unwrap() + ); + let res = Command::new("python3") + .args(&[script_path.file_name().unwrap().to_str().unwrap(), &*app]) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .current_dir(abs_script_dir) + .spawn() + .unwrap() + .wait() + .await + .unwrap(); + if !res.success() { + panic!( + "prepare data for {} with script {} failed", + app, + script_path.to_str().unwrap() + ); + } + } + + for data in app_entry.prepare_data.iter() { + let data_path = PathBuf::from("prepare_data").join(&app).join(data); + if !data_path.exists() { + panic!("prepare data failed {:?}", data); + } + prepare_data + .entry(app.to_owned()) + .or_insert(vec![]) + .push(data_path); + } + // for data in app_entry.prepare_data.iter() { + // prepare_data.push(data.clone()); + // } + } + + prepare_data +} diff --git a/bencher/src/config.rs b/bencher/src/config.rs new file mode 100644 index 0000000..5233d70 --- /dev/null +++ b/bencher/src/config.rs @@ -0,0 +1,104 @@ +use serde_yaml::Value; +use std::{collections::HashMap, fs::File, io::BufReader}; + +#[derive(serde::Deserialize, Debug, Clone)] +pub struct FnDetails { + pub args: Option>, +} + +#[derive(serde::Deserialize, Debug, Clone)] +pub struct AppFnEntry { + pub prepare_data: Vec, + pub prepare_scripts: Vec, + pub fns: HashMap, +} + +#[derive(serde::Deserialize, Debug, Clone)] +pub struct AppFnReplica { + pub source: String, + pub fns: HashMap, +} + +// app: +// prepare_data: +// - file1 +// prepare_scripts: +// - script1 +// fns: +// fn1: +// args: +// pub type AppFnEntries = HashMap; + +#[derive(serde::Deserialize, Debug, Clone)] +pub struct MinioConfig { + pub endpoint: String, + pub access_key: String, + pub secret_key: String, + pub compose_path: String, +} + +impl MinioConfig { + pub fn one_line(&self) -> String { + format!("{},{},{}", self.endpoint, self.access_key, self.secret_key) + } +} + +#[derive(serde::Deserialize, Debug, Clone)] +pub struct Config { + pub models: HashMap, + pub replicas: HashMap, + pub benchlist: HashMap, + pub minio: MinioConfig, +} + +impl Config { + // todo: add replica support + pub fn get(&self, app: &str) -> Option<&AppFnEntry> { + self.models.get(app) + } + + pub fn get_fn_details(&self, app: &str, func: &str) -> Option { + let mut fndetail = if self.models.contains_key(app) { + self.models.get(app).unwrap().fns.get(func).cloned() + } else if let Some(replica) = self.replicas.get(app) { + // replica args will cover model args + let source = replica.source.clone(); + let source_fn_details = self.get_fn_details(&source, func); + if let Some(mut source_fn_details) = source_fn_details { + // cover by replica args + for (key, value) in replica.fns.get(func).unwrap().args.as_ref().unwrap() { + source_fn_details + .args + .as_mut() + .unwrap() + .insert(key.clone(), value.clone()); + } + Some(source_fn_details) + } else { + None + } + } else { + None + }; + fndetail.map(|mut fndetail| { + let args = fndetail.args.as_mut().unwrap(); + if let Some(Value::Bool(true)) = args.get("use_minio") { + args.insert("use_minio".to_owned(), Value::from(self.minio.one_line())); + } else { + // remove use_minio + args.remove("use_minio"); + } + + fndetail + }) + } +} + +pub fn load_config() -> Config { + let f = File::open("app_fn_entries.yaml").expect("open app_fn_entries.yaml failed"); + let freader = BufReader::new(f); + let app_fn_entries: Config = serde_yaml::from_reader(freader).unwrap_or_else(|e| { + panic!("parse 'app_fn_entries.yaml' failed with {:?}", e); + }); + app_fn_entries +} diff --git a/bencher/src/main.rs b/bencher/src/main.rs index b0e0cdc..46f314a 100644 --- a/bencher/src/main.rs +++ b/bencher/src/main.rs @@ -1,4 +1,7 @@ +mod common_prepare; +mod config; mod metric; +mod minio; mod mode_bench; mod mode_call_once; mod mode_first_call; @@ -10,11 +13,13 @@ mod platform_ow; mod platform_wl; mod prometheus; mod test_call_once; +mod util; // mod reponse; use async_trait::async_trait; use clap::Parser; +use config::Config; use enum_dispatch::enum_dispatch; use goose::prelude::*; use parse::Cli; @@ -35,68 +40,6 @@ use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; use tracing_subscriber::Layer; -fn new_bucket() -> Bucket { - let (tx, rx) = mpsc::channel(); - tokio::spawn(async move { - let bucket_name = "serverless-bench"; - let region = Region::Custom { - region: "eu-central-1".to_owned(), - endpoint: "http://192.168.31.96:9009".to_owned(), - }; - let credentials = Credentials { - access_key: Some("minioadmin".to_owned()), - secret_key: Some("minioadmin123".to_owned()), - security_token: None, - session_token: None, - expiration: None, - }; - - let mut bucket = Bucket::new(bucket_name, region.clone(), credentials.clone()) - .unwrap() - .with_path_style(); - - let bucket_exist = match bucket.exists().await { - Err(e) => { - tracing::warn!("test s3 is not started, automatically start it"); - // docker-compose up -d at ../middlewares/minio/ - process::Command::new("docker-compose") - .arg("up") - .arg("-d") - .current_dir(PathBuf::from("../middlewares/minio/")) - .output() - .expect("failed to start minio"); - tokio::time::sleep(Duration::from_secs(15)).await; - bucket.exists().await.unwrap() - } - Ok(ok) => ok, - }; - - if bucket_exist { - for b in bucket.list("".to_owned(), None).await.unwrap() { - bucket.delete_object(b.name).await.unwrap(); - // bucket.delete().await.unwrap(); - } - } else { - bucket = Bucket::create_with_path_style( - bucket_name, - region, - credentials, - BucketConfiguration::default(), - ) - .await - .unwrap() - .bucket; - } - - tx.send(bucket); - }); - rx.recv().unwrap() -} - -lazy_static::lazy_static! { - pub static ref BUCKET:Bucket=new_bucket(); -} - fn is_bench_mode(cli: &Cli) -> bool { cli.bench_mode > 0 } @@ -196,10 +139,18 @@ enum PlatformOpsBind { #[enum_dispatch] pub trait PlatformOps: Send + 'static { + fn cli(&self) -> &Cli; async fn remove_all_fn(&self); async fn upload_fn(&mut self, demo: &str, rename_sub: &str); async fn call_fn(&self, app: &str, func: &str, arg_json_value: &serde_json::Value) -> String; + async fn prepare_apps_bin(&self, apps: Vec, config: &Config); } + +// pub trait PlatformOpsExt: PlatformOps { +// fn config_path_string(&self) -> String { +// self.cli().config_path() +// } +// } // pub struct CallRes { // out: String, // err: String, @@ -252,15 +203,30 @@ async fn main() -> Result<(), GooseError> { start_tracing(); + // tracing::debug!( + // "bencher running at dir {}", + // std::env::current_dir().unwrap() + // ); + // debug abs running dir + + tracing::debug!( + "bencher running at dir {}", + std::env::current_dir().unwrap().display() + ); + let cli = Cli::parse(); cli.check_app_fn().check_platform().check_mode(); + let config = config::load_config(); + + minio::init_bucket(&config.minio).await; + let seed = "helloworld"; tracing::debug!("Preparing paltform >>>"); let mut platform = if cli.with_ow > 0 { - PlatformOpsBind::from(platform_ow::PlatfromOw::default()) + PlatformOpsBind::from(platform_ow::PlatfromOw::new(&cli, &config)) } else if cli.with_wl > 0 { - PlatformOpsBind::from(platform_wl::PlatfromWl::new()) + PlatformOpsBind::from(platform_wl::PlatfromWl::new(&cli, config.clone())) } else { panic!("no platform specified, please specify by --with-ow or --with-wl"); }; @@ -272,6 +238,11 @@ async fn main() -> Result<(), GooseError> { tracing::debug!("Preparing: {preparing}"); tracing::debug!("==========================="); } + if is_prepare_mode(&cli) { + common_prepare::prepare_data(cli.target_apps(), &config).await; + platform.prepare_apps_bin(cli.target_apps(), &config).await; + } + if is_bench_mode(&cli) { print_mode("bench", is_bench_mode(&cli)); unimplemented!(); @@ -280,16 +251,16 @@ async fn main() -> Result<(), GooseError> { } else if is_first_call_mode(&cli) { print_mode("first_call", is_bench_mode(&cli)); if is_prepare_mode(&cli) { - mode_first_call::prepare(&mut platform, seed.to_owned(), cli.clone()).await; + mode_first_call::prepare(&mut platform, &config, cli.clone()).await; } else { - mode_first_call::call(&mut platform, cli).await; + mode_first_call::call(&mut platform, cli, &config).await; } } else if is_once_mode(&cli) { print_mode("first_call", is_bench_mode(&cli)); if is_prepare_mode(&cli) { mode_call_once::prepare(&mut platform, seed.to_owned(), cli.clone()).await; } else { - mode_call_once::call(&mut platform, cli).await; + mode_call_once::call(&mut platform, cli, &config).await; } } else { panic!("unreachable") diff --git a/bencher/src/minio.rs b/bencher/src/minio.rs new file mode 100644 index 0000000..c13993d --- /dev/null +++ b/bencher/src/minio.rs @@ -0,0 +1,84 @@ +use std::{path::PathBuf, process::Stdio, time::Duration}; + +use s3::{creds::Credentials, Bucket, BucketConfiguration, Region}; +use tokio::{process::Command, sync::OnceCell}; + +use crate::{config::MinioConfig, util::CommandDebugStdio}; + +pub async fn init_bucket(config: &MinioConfig) -> Bucket { + let bucket_name = "serverless-bench"; + let region = Region::Custom { + region: "eu-central-1".to_owned(), + endpoint: config.endpoint.to_owned(), + }; + let credentials = Credentials { + access_key: Some(config.access_key.to_owned()), + secret_key: Some(config.secret_key.to_owned()), + security_token: None, + session_token: None, + expiration: None, + }; + + let mut bucket = Bucket::new(bucket_name, region.clone(), credentials.clone()) + .unwrap() + .with_path_style(); + + let bucket_exist = match bucket.exists().await { + Err(e) => { + tracing::warn!("test s3 is not started, automatically start it"); + // docker-compose up -d at ../middlewares/minio/ + // check if docker-compose is installed + if !Command::new("docker-compose") + .arg("--version") + .output() + .await + .is_ok() + { + panic!("docker-compose is not installed"); + } + let (_, _, mut res) = Command::new("docker-compose") + .arg("up") + .arg("-d") + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .current_dir(PathBuf::from(config.compose_path.clone())) + .spawn_debug() + .await; + let res = res.wait().await.unwrap(); + + assert!( + res.success(), + "failed to start minio at {}", + config.compose_path + ); + tokio::time::sleep(Duration::from_secs(15)).await; + bucket.exists().await.unwrap() + } + Ok(ok) => ok, + }; + + if bucket_exist { + for b in bucket.list("".to_owned(), None).await.unwrap() { + bucket.delete_object(b.name).await.unwrap(); + // bucket.delete().await.unwrap(); + } + } else { + bucket = Bucket::create_with_path_style( + bucket_name, + region, + credentials, + BucketConfiguration::default(), + ) + .await + .unwrap() + .bucket; + } + + BUCKET.set(bucket).unwrap(); + + BUCKET.get().unwrap().clone() +} + +lazy_static::lazy_static! { + pub static ref BUCKET: OnceCell = OnceCell::new(); +} diff --git a/bencher/src/mode_call_once.rs b/bencher/src/mode_call_once.rs index cd9df4a..a9242e7 100644 --- a/bencher/src/mode_call_once.rs +++ b/bencher/src/mode_call_once.rs @@ -7,18 +7,19 @@ use std::{ use clap::Args; use serde_yaml::Value; -use crate::{parse::Cli, Metric, PlatformOps, PlatformOpsBind, BUCKET}; +use crate::{config::Config, parse::Cli, Metric, PlatformOps, PlatformOpsBind}; pub async fn prepare(platform: &mut PlatformOpsBind, seed: String, cli: Cli) { platform.remove_all_fn().await; - platform.upload_fn("simple_demo", "").await; + platform.upload_fn(&cli.app().unwrap(), "").await; // self.prepare_img(&seed); } -pub async fn call(platform: &mut PlatformOpsBind, cli: Cli) -> Metric { +pub async fn call(platform: &mut PlatformOpsBind, cli: Cli, config: &Config) -> Metric { // read image from file // let img = fs::read("img_resize/image_0.jpg").unwrap(); - + let app = cli.app().unwrap(); + let func = cli.func().unwrap(); // BUCKET // // .lock() // // .await @@ -26,7 +27,8 @@ pub async fn call(platform: &mut PlatformOpsBind, cli: Cli) -> Metric { // .await // .unwrap(); - let args = cli.func_details().args; + let fndetail = config.get_fn_details(&app, &func).unwrap(); + // let args = cli.func_details().args; // let arg = Args { // image_s3_path: format!("image_{}.jpg", 0), // target_width: 50, @@ -41,8 +43,12 @@ pub async fn call(platform: &mut PlatformOpsBind, cli: Cli) -> Metric { // .call_fn("img_resize", "resize", &serde_json::to_value(args).unwrap()) // .await; let output = platform - .call_fn("simple_demo", "simple", &serde_json::to_value(args).unwrap()) - .await; + .call_fn( + &cli.app().unwrap(), + &cli.func().unwrap(), + &serde_json::to_value(fndetail.args).unwrap(), + ) + .await; // tracing::info!("debug output {}", output); let res: serde_json::Value = serde_json::from_str(&output).unwrap_or_else(|e| { tracing::error!("failed to parse json: {}", e); @@ -84,16 +90,35 @@ pub async fn call(platform: &mut PlatformOpsBind, cli: Cli) -> Metric { .expect("Time went backwards") .as_millis() as u64; + // | println!("debug output: {:?}", output); println!( - "\ntotal request latency: {}", + "\ntotal request latency: {} ms", receive_resp_time - start_call_ms ); println!("- req trans time: {}", req_arrive_time - start_call_ms); + // if recover_begin_time<=req_arrive_time{ + + // } + // 系统调用函数时刻 - 请求到达系统 println!("- app verify time: {}", bf_exec_time - req_arrive_time); - println!("- cold start time: {}", recover_begin_time - bf_exec_time); - println!("- cold start time2: {}", fn_start_ms - recover_begin_time); + // 开始冷启动时刻 + println!( + "- cold start time: {}", + if recover_begin_time > bf_exec_time { + recover_begin_time - bf_exec_time + } else { + 0 + } + ); + + // 冷启动和请求到达系统谁更新 + println!( + "- cold start time2: {}", + fn_start_ms - recover_begin_time.max(req_arrive_time) + ); + println!("- exec time:{}", fn_end_ms - fn_start_ms); if fn_end_ms > receive_resp_time { println!( diff --git a/bencher/src/mode_first_call.rs b/bencher/src/mode_first_call.rs index 872fe13..694bb3e 100644 --- a/bencher/src/mode_first_call.rs +++ b/bencher/src/mode_first_call.rs @@ -1,14 +1,15 @@ use crate::{ - metric::Recorder, mode_call_once, parse::Cli, parse_platform::Platform, + config::Config, metric::Recorder, mode_call_once, parse::Cli, parse_platform::Platform, parse_test_mode::TestMode, PlatformOps, PlatformOpsBind, }; -pub async fn prepare(platform: &mut PlatformOpsBind, seed: String, cli: Cli) { +pub async fn prepare(platform: &mut PlatformOpsBind, config: &Config, cli: Cli) { platform.remove_all_fn().await; + platform.prepare_apps_bin(cli.target_apps(), config).await; // cli.prepare_img(&seed); } -pub async fn call(platform: &mut PlatformOpsBind, cli: Cli) { +pub async fn call(platform: &mut PlatformOpsBind, cli: Cli, config: &Config) { let app = cli.app().expect("first call mode must have app name"); let func = cli.func().expect("first call mode must have func name"); @@ -17,7 +18,7 @@ pub async fn call(platform: &mut PlatformOpsBind, cli: Cli) { let mut metrics = vec![]; for _ in 0..20 { platform.upload_fn("simple_demo", "").await; - let m = mode_call_once::call(platform, cli.clone()).await; //self.call_once(cli.clone()).await; + let m = mode_call_once::call(platform, cli.clone(), config).await; //self.call_once(cli.clone()).await; recorder.record(m.clone()); // prometheus::upload_fn_call_metric("simple_demo", &m).await; metrics.push(m); diff --git a/bencher/src/parse.rs b/bencher/src/parse.rs index a413a80..8f18599 100644 --- a/bencher/src/parse.rs +++ b/bencher/src/parse.rs @@ -9,6 +9,9 @@ use clap::{command, Command}; use clap::{Parser, Subcommand}; use serde_yaml::Value; +use crate::config::Config; +use crate::config::FnDetails; + #[derive(Parser, Clone)] #[command(version, about, long_about = None)] pub struct Cli { @@ -30,30 +33,15 @@ pub struct Cli { // create many function copy and collect the average cold start #[arg(long, action = clap::ArgAction::Count)] pub first_call_mode: u8, -} - -#[derive(serde::Deserialize, Debug, Clone)] -pub struct FnDetails { - pub args: Option>, -} -#[derive(serde::Deserialize, Debug)] -pub struct AppFnEntry { - pub prepare_data: Vec, - pub prepare_scripts: Vec, - pub fns: HashMap, + #[arg(short, long, default_value = "../middlewares/cluster_config.yml")] + config: String, } -// app: -// prepare_data: -// - file1 -// prepare_scripts: -// - script1 -// fns: -// fn1: -// args: -pub type AppFnEntries = HashMap; impl Cli { + pub fn target_apps(&self) -> Vec { + vec![self.app().unwrap()] + } pub fn app(&self) -> Option { if self.app_fn.find("/").is_none() { return None; @@ -68,29 +56,34 @@ impl Cli { iter.next(); return Some(iter.next().unwrap().to_owned()); } - pub fn func_details(&self) -> FnDetails { - let app = self.app().unwrap_or_else(|| { - panic!("missing app name, cur input is {}", self.app_fn); - }); - let func = self.func().unwrap_or_else(|| { - panic!("missing fn name, cur input is {}", self.app_fn); - }); + // pub fn func_details(&self, config: &Config) -> FnDetails { + // let app = self.app().unwrap_or_else(|| { + // panic!("missing app name, cur input is {}", self.app_fn); + // }); + // let func = self.func().unwrap_or_else(|| { + // panic!("missing fn name, cur input is {}", self.app_fn); + // }); - //read 'app_fn_entries.yaml' - let f = File::open("app_fn_entries.yaml").expect("open app_fn_entries.yaml failed"); - let freader = BufReader::new(f); - let app_fn_entries: AppFnEntries = serde_yaml::from_reader(freader).unwrap_or_else(|e| { - panic!("parse 'app_fn_entries.yaml' failed with {:?}", e); - }); + // //read 'app_fn_entries.yaml' + // if config.models.contains_key(&app) { - let f = app_fn_entries - .get(&app) - .unwrap_or_else(|| panic!("app '{}' is not in app_fn_entries.yaml", app)) - .fns - .get(&func) - .unwrap_or_else(|| panic!("function '{}' is not in app '{}' in app_fn_entries.yaml", func, app)); - f.clone() - } + // }else{ + // // replica, read source first, then compose fn details + // } + + // let f = config + // .get(&app) + // .unwrap_or_else(|| panic!("app '{}' is not in app_fn_entries.yaml", app)) + // .fns + // .get(&func) + // .unwrap_or_else(|| { + // panic!( + // "function '{}' is not in app '{}' in app_fn_entries.yaml", + // func, app + // ) + // }); + // f.clone() + // } pub fn check_app_fn(&self) -> &Self { let app = self.app().unwrap_or_else(|| { panic!("missing app name, cur input is {}", self.app_fn); @@ -102,7 +95,7 @@ impl Cli { //read 'app_fn_entries.yaml' let f = File::open("app_fn_entries.yaml").expect("open app_fn_entries.yaml failed"); let freader = BufReader::new(f); - let app_fn_entries: AppFnEntries = serde_yaml::from_reader(freader).unwrap_or_else(|e| { + let app_fn_entries: Config = serde_yaml::from_reader(freader).unwrap_or_else(|e| { panic!("parse 'app_fn_entries.yaml' failed with {:?}", e); }); @@ -111,7 +104,12 @@ impl Cli { .unwrap_or_else(|| panic!("app '{}' is not in app_fn_entries.yaml", app)) .fns .get(&func) - .unwrap_or_else(|| panic!("function '{}' is not in app '{}' in app_fn_entries.yaml", func, app)); + .unwrap_or_else(|| { + panic!( + "function '{}' is not in app '{}' in app_fn_entries.yaml", + func, app + ) + }); self } pub fn check_platform(&self) -> &Self { @@ -130,4 +128,8 @@ impl Cli { ); self } + + pub fn cluster_config(&self) -> String { + self.config.clone() + } } diff --git a/bencher/src/platform_ow.rs b/bencher/src/platform_ow.rs index 15a0dce..5e9ea17 100644 --- a/bencher/src/platform_ow.rs +++ b/bencher/src/platform_ow.rs @@ -6,21 +6,55 @@ use std::{ }; use tokio::process::{self, Command}; -use crate::PlatformOps; +use crate::{config::Config, parse::Cli, PlatformOps}; pub struct PlatfromOw { pub gen_demos: HashSet, + cli: Cli, + config: Config, } -impl Default for PlatfromOw { - fn default() -> Self { - PlatfromOw { +impl PlatfromOw { + pub fn new(cli: &Cli, config: &Config) -> Self { + Self { gen_demos: HashSet::new(), + cli: cli.clone(), + config: config.clone(), } } } +// impl Default for PlatfromOw { +// fn default() -> Self { +// PlatfromOw { +// gen_demos: HashSet::new(), +// } +// } +// } + impl PlatformOps for PlatfromOw { + async fn prepare_apps_bin(&self, apps: Vec, config: &Config) { + process::Command::new("python3") + .args(&["../middlewares/openwhisk/7.clean_all_fns.py"]) + .status() + .await + .expect("Failed to clean openwhisk fns"); + + for app in apps { + let mut cmd2 = process::Command::new("python3"); + cmd2.args(&["../middlewares/openwhisk/8.add_func.py", &app, &app]); + tracing::info!("run cmd: {:?}", cmd2); + let res = cmd2 + .status() + .await + .expect(&format!("Failed to add func {}", app)); + assert!(res.success()); + } + } + + fn cli(&self) -> &Cli { + &self.cli + } async fn remove_all_fn(&self) { process::Command::new("python3") .args(&["../middlewares/openwhisk/7.clean_all_fns.py"]) diff --git a/bencher/src/platform_wl.rs b/bencher/src/platform_wl.rs index d902d9c..53fbce0 100644 --- a/bencher/src/platform_wl.rs +++ b/bencher/src/platform_wl.rs @@ -1,35 +1,43 @@ use tokio::process; +use crate::config::Config; +use crate::parse::Cli; use crate::PlatformOps; use std::collections::HashSet; use std::{collections::HashMap, fs::File, io::BufReader, str::from_utf8}; pub struct PlatfromWl { + cli: Cli, master_url: String, worker_url: String, - gen_demos: HashSet, + // gen_demos: HashSet, + config: Config, } impl PlatfromWl { - pub fn new() -> Self { - let file = File::open("../middlewares/cluster_config.yml").unwrap(); - let reader = BufReader::new(file); - let config: HashMap> = - serde_yaml::from_reader(reader).unwrap(); + pub fn new(cli: &Cli, config: Config) -> Self { let mut res = Self { + cli: cli.clone(), master_url: "".to_owned(), worker_url: "".to_owned(), - gen_demos: HashSet::new(), + // gen_demos: HashSet::new(), + config: config.clone(), }; + + let file = File::open(cli.cluster_config()).unwrap(); + let reader = BufReader::new(file); + let config: HashMap> = + serde_yaml::from_reader(reader).unwrap(); + for (_, conf) in config { if conf.contains_key("is_master") { res.master_url = format!( - "http://{}:2501", + "http://{}", conf.get("ip").unwrap().as_str().unwrap().to_owned() ); } else { res.worker_url = format!( - "http://{}:2501", + "http://{}", conf.get("ip").unwrap().as_str().unwrap().to_owned() ); } @@ -39,19 +47,39 @@ impl PlatfromWl { } impl PlatformOps for PlatfromWl { - async fn remove_all_fn(&self) {} - async fn upload_fn(&mut self, demo: &str, rename_sub: &str) { - if !self.gen_demos.contains(demo) { + async fn prepare_apps_bin(&self, apps: Vec, config: &Config) { + let model_apps: Vec = apps + .clone() + .into_iter() + .filter(|app| config.models.contains_key(app)) + .collect(); + + for app in model_apps { let res = process::Command::new("python3") - .args(&["../demos/scripts/1.gen_waverless_app.py", demo]) + .args(&["../demos/scripts/1.gen_waverless_app.py", &app]) .status() .await - .expect(&format!("Failed to gen demo {}", demo)); - assert!(res.success()); - self.gen_demos.insert(demo.to_owned()); + .expect(&format!("Failed to gen demo {}", app)); + assert!(res.success(), "Failed to gen demo app: {}", app); + // self.gen_demos.insert(demo.to_owned()); } + } + + fn cli(&self) -> &Cli { + &self.cli + } + async fn remove_all_fn(&self) {} + async fn upload_fn(&mut self, demo: &str, rename_sub: &str) { + // if !self.gen_demos.contains(demo) { + + // } process::Command::new("python3") - .args(&["../middlewares/waverless/3.add_func.py", demo, rename_sub]) + .args(&[ + "../middlewares/waverless/3.add_func.py", + demo, + rename_sub, + &self.cli().cluster_config(), + ]) .status() .await .expect(&format!("Failed to add func {} as {}", demo, rename_sub)); diff --git a/bencher/src/test_call_once.rs b/bencher/src/test_call_once.rs index 1f3ad72..4b4c52d 100644 --- a/bencher/src/test_call_once.rs +++ b/bencher/src/test_call_once.rs @@ -7,15 +7,24 @@ use std::{ use clap::Args; use serde_yaml::Value; -use crate::{parse::Cli, Metric, PlatformOps, PlatformOpsBind, BUCKET}; +use crate::{config::Config, parse::Cli, Metric, PlatformOps, PlatformOpsBind}; pub async fn prepare(platform: &mut PlatformOpsBind, seed: String, cli: Cli) { platform.remove_all_fn().await; - platform.upload_fn("simple_demo", "/root/ygy/demos/simple_demo/pack").await; + platform + .upload_fn("simple_demo", "/root/ygy/demos/simple_demo/pack") + .await; } -pub async fn call(platform: &mut PlatformOpsBind, cli: Cli) -> Metric { - let args = cli.func_details().args.unwrap_or_default(); +// call once mod only got one function +pub async fn call(platform: &mut PlatformOpsBind, cli: Cli, config: &Config) -> Metric { + let app = cli.app().unwrap(); + let func = cli.func().unwrap(); + let args = config + .get_fn_details(&app, &func) + .unwrap() + .args + .unwrap_or_default(); let start_call_ms = SystemTime::now() .duration_since(UNIX_EPOCH) @@ -23,7 +32,7 @@ pub async fn call(platform: &mut PlatformOpsBind, cli: Cli) -> Metric { .as_millis() as u64; let output = platform - .call_fn("simple_demo", "simple", &serde_json::to_value(args).unwrap()) + .call_fn(&app, &func, &serde_json::to_value(args).unwrap()) .await; let res: serde_json::Value = serde_json::from_str(&output).unwrap_or_else(|e| { diff --git a/bencher/src/util.rs b/bencher/src/util.rs new file mode 100644 index 0000000..a1dc853 --- /dev/null +++ b/bencher/src/util.rs @@ -0,0 +1,52 @@ +use tokio::{ + io::{AsyncBufReadExt, BufReader}, + process::{Child, Command}, +}; + +pub trait CommandDebugStdio { + async fn spawn_debug( + &mut self, + ) -> ( + tokio::task::JoinHandle, + tokio::task::JoinHandle, + Child, + ); +} + +impl CommandDebugStdio for Command { + async fn spawn_debug( + &mut self, + ) -> ( + tokio::task::JoinHandle, + tokio::task::JoinHandle, + Child, + ) { + let mut child = self.spawn().unwrap(); + let stdout = child.stdout.take().unwrap(); + let stderr = child.stderr.take().unwrap(); + + // 分别处理 stdout 和 stderr + let mut stdout_reader = BufReader::new(stdout).lines(); + let mut stderr_reader = BufReader::new(stderr).lines(); + + let stdout_task = tokio::spawn(async move { + let mut all = String::new(); + while let Ok(Some(line)) = stdout_reader.next_line().await { + println!("[STDOUT] {}", line); + all += &format!("[STDOUT] {}\n", line); + } + all + }); + + let stderr_task = tokio::spawn(async move { + let mut all = String::new(); + while let Ok(Some(line)) = stderr_reader.next_line().await { + eprintln!("[STDERR] {}", line); + all += &format!("[STDERR] {}\n", line); + } + all + }); + + (stdout_task, stderr_task, child) + } +} diff --git a/demos/_java_serverless_lib/core/pom.xml b/demos/_java_serverless_lib/core/pom.xml index 98e5708..0d3af23 100644 --- a/demos/_java_serverless_lib/core/pom.xml +++ b/demos/_java_serverless_lib/core/pom.xml @@ -44,6 +44,11 @@ org.crac crac + + io.minio + minio + 8.5.2 + diff --git a/demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/BeanConfig.java b/demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/BeanConfig.java index 402edb0..b3101f3 100644 --- a/demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/BeanConfig.java +++ b/demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/BeanConfig.java @@ -24,4 +24,9 @@ public RpcHandleOwner rpcHandleOwner() { public CracManager cracManager() { return new CracManager(); } + + @Bean + public DataApi dataApi() { + return new DataApi(); + } } diff --git a/demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/DataApi.java b/demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/DataApi.java new file mode 100644 index 0000000..e30dfdc --- /dev/null +++ b/demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/DataApi.java @@ -0,0 +1,202 @@ +package io.serverless_lib; + +import io.minio.BucketExistsArgs; +import io.minio.GetObjectArgs; +import io.minio.MinioClient; +import io.minio.MakeBucketArgs; +import io.minio.PutObjectArgs; +import io.minio.RemoveObjectArgs; +import io.minio.errors.MinioException; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.Map; + +/** + * DataApi用于处理数据存储,支持内存模式和MinIO模式 + */ +public class DataApi { + + private volatile boolean initialized = false; + private Map memoryStorage; + private MinioClient minioClient; + private String storageBucket; + private String storageMode; + + /** + * 延迟初始化函数,使用线程安全的双重检查锁定模式 + * @param use_minio MinIO连接字符串,为空时使用内存Map存储 + */ + public void init(String use_minio) { + // 第一次检查,避免每次调用都加锁 + if (initialized) { + return; + } + + // 使用同步块保护初始化过程 + synchronized (this) { + // 二次检查,防止其他线程已经完成了初始化 + if (initialized) { + return; + } + + if (use_minio == null || use_minio.isEmpty()) { + // 使用内存Map模式 + memoryStorage = new ConcurrentHashMap<>(); + storageMode = "memory"; + System.out.println("DataApi initialized in memory mode"); + } else { + // 连接到MinIO + try { + // 解析MinIO连接字符串 (格式示例: "http://localhost:9000,accessKey,secretKey,bucketName") + String[] parts = use_minio.split(","); + String endpoint = parts[0]; + String accessKey = parts.length > 1 ? parts[1] : ""; + String secretKey = parts.length > 2 ? parts[2] : ""; + storageBucket = parts.length > 3 ? parts[3] : "serverless-bench"; + + minioClient = MinioClient.builder() + .endpoint(endpoint) + .credentials(accessKey, secretKey) + .build(); + + // 确保存储桶存在 + boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(storageBucket).build()); + if (!found) { + minioClient.makeBucket(MakeBucketArgs.builder().bucket(storageBucket).build()); + } + + storageMode = "minio"; + System.out.println("DataApi initialized in MinIO mode: " + endpoint); + } catch (Exception e) { + // 连接MinIO失败,回退到内存模式 + memoryStorage = new ConcurrentHashMap<>(); + storageMode = "memory"; + System.err.println("Failed to connect to MinIO, fallback to memory mode: " + e.getMessage()); + } + } + + // 最后设置初始化标志 + initialized = true; + } + } + + /** + * 保存数据 + * @param key 键 + * @param value 字节数组值 + * @throws IOException 操作失败时抛出异常 + */ + public void put(String key, byte[] value) throws IOException { + if (!initialized) { + throw new IllegalStateException("DataApi not initialized. Call init() first."); + } + + if ("memory".equals(storageMode)) { + memoryStorage.put(key, value); + } else { + try { + // 将字节数组上传到MinIO + ByteArrayInputStream bais = new ByteArrayInputStream(value); + minioClient.putObject( + PutObjectArgs.builder() + .bucket(storageBucket) + .object(key) + .stream(bais, value.length, -1) + .contentType("application/octet-stream") + .build() + ); + bais.close(); + } catch (MinioException | InvalidKeyException | NoSuchAlgorithmException e) { + throw new IOException("Failed to put object to MinIO: " + e.getMessage(), e); + } + } + } + + /** + * 获取数据 + * @param key 键 + * @return 字节数组值,如果键不存在则返回null + * @throws IOException 操作失败时抛出异常 + */ + public byte[] get(String key) throws IOException { + if (!initialized) { + throw new IllegalStateException("DataApi not initialized. Call init() first."); + } + + if ("memory".equals(storageMode)) { + return memoryStorage.get(key); + } else { + try { + // 从MinIO获取对象 + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + InputStream stream = minioClient.getObject( + GetObjectArgs.builder() + .bucket(storageBucket) + .object(key) + .build() + ); + + // 读取字节到输出流 + byte[] buffer = new byte[16384]; + int bytesRead; + while ((bytesRead = stream.read(buffer)) > 0) { + baos.write(buffer, 0, bytesRead); + } + + stream.close(); + baos.close(); + return baos.toByteArray(); + + } catch (MinioException | InvalidKeyException | NoSuchAlgorithmException e) { + throw new IOException("Failed to get object from MinIO: " + e.getMessage(), e); + } + } + } + + /** + * 删除数据 + * @param key 要删除的键 + * @throws IOException 操作失败时抛出异常 + */ + public void delete(String key) throws IOException { + if (!initialized) { + throw new IllegalStateException("DataApi not initialized. Call init() first."); + } + + if ("memory".equals(storageMode)) { + memoryStorage.remove(key); + } else { + try { + // 从MinIO删除对象 + minioClient.removeObject( + RemoveObjectArgs.builder() + .bucket(storageBucket) + .object(key) + .build() + ); + } catch (MinioException | InvalidKeyException | NoSuchAlgorithmException e) { + throw new IOException("Failed to delete object from MinIO: " + e.getMessage(), e); + } + } + } + + /** + * 检查是否已初始化 + */ + public boolean isInitialized() { + return initialized; + } + + /** + * 获取当前存储模式 + */ + public String getStorageMode() { + return storageMode; + } +} \ No newline at end of file diff --git a/demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/UdsBackend.java b/demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/UdsBackend.java index 5811017..caeb486 100644 --- a/demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/UdsBackend.java +++ b/demos/_java_serverless_lib/core/src/main/java/io/serverless_lib/UdsBackend.java @@ -212,6 +212,7 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) // 读取长度字段 int length = in.readInt(); int taskId = in.readInt(); + System.out.println("Received message from server: " + length + " bytes, taskId: " + taskId); // 确保有足够的字节来读取数据 if (in.readableBytes() < length) { diff --git a/demos/_java_serverless_lib/scripts/prepare_protoc.py b/demos/_java_serverless_lib/scripts/prepare_protoc.py index 33de384..cdc6611 100644 --- a/demos/_java_serverless_lib/scripts/prepare_protoc.py +++ b/demos/_java_serverless_lib/scripts/prepare_protoc.py @@ -31,7 +31,7 @@ def run_cmd_return(cmd): with open("config.yaml") as f: conf=yaml.safe_load(f) waverless_rel_path=conf["waverless_rel_path"] -proto_src_dir=os.path.join(waverless_rel_path,"src/worker/func/shared/") +proto_src_dir=os.path.join(waverless_rel_path,"src/main/src/general/app/app_shared/") proto_src=os.path.join(proto_src_dir,'process_rpc_proto.proto') diff --git a/demos/img_resize/src/main/java/test/functions/Resize.java b/demos/img_resize/src/main/java/test/functions/Resize.java index 1cbf9d9..57d229c 100644 --- a/demos/img_resize/src/main/java/test/functions/Resize.java +++ b/demos/img_resize/src/main/java/test/functions/Resize.java @@ -16,15 +16,20 @@ import java.io.InputStream; import java.nio.ByteBuffer; import javax.imageio.ImageIO; +import org.springframework.beans.factory.annotation.Autowired; +import io.serverless_lib.DataApi; public class Resize { // Initialize Minio Client - MinioClient minioClient = - MinioClient.builder() - .endpoint("http://192.168.31.96:9009") - .credentials("minioadmin", "minioadmin123") - .build(); + // MinioClient minioClient = + // MinioClient.builder() + // .endpoint("http://192.168.31.96:9009") + // .credentials("minioadmin", "minioadmin123") + // .build(); + @Autowired + DataApi dataApi; + // 辅助方法:将输入流读取到 ByteBuffer private static ByteBuffer readToByteBuffer(InputStream inputStream) throws IOException { // Start with a default buffer size @@ -80,30 +85,41 @@ public JsonObject call(JsonObject args) { String imagepath = args.get("image_s3_path").getAsString(); int targetWidth = args.get("target_width").getAsInt(); int targetHeight = args.get("target_height").getAsInt(); + String useMinio = args.get("use_minio").getAsString(); + // print useMinio + System.out.println("--------------------------------"); + System.out.println("imagepath: " + imagepath); + System.out.println("targetWidth: " + targetWidth); + System.out.println("targetHeight: " + targetHeight); + System.out.println("useMinio: " + useMinio); + System.out.println("--------------------------------"); + + dataApi.init(useMinio); JsonObject result = new JsonObject(); try { // Download the file from the bucket - GetObjectArgs getObjectArgs = GetObjectArgs.builder() - .bucket("serverless-bench") - .object(imagepath) - .build(); - InputStream downloadedStream = minioClient.getObject(getObjectArgs); - ByteBuffer bf=readToByteBuffer(downloadedStream); + // GetObjectArgs getObjectArgs = GetObjectArgs.builder() + // .bucket("serverless-bench") + // .object(imagepath) + // .build(); + byte[] imageData = dataApi.get(imagepath); + // ByteBuffer bf=readToByteBuffer(downloadedStream); - byte[] resizedImage = resizeImage(bf.array(), targetWidth, targetHeight); + byte[] resizedImage = resizeImage(imageData, targetWidth, targetHeight); - ByteArrayInputStream inputStream = new ByteArrayInputStream(resizedImage); - - minioClient.putObject( - PutObjectArgs.builder() - .bucket("serverless-bench") - .object(renameFile(imagepath)) - .stream(inputStream, resizedImage.length, -1) - .contentType("image/jpeg") - .build() - ); + // ByteArrayInputStream inputStream = new ByteArrayInputStream(resizedImage); + + dataApi.put(renameFile(imagepath), resizedImage); + // minioClient.putObject( + // PutObjectArgs.builder() + // .bucket("serverless-bench") + // .object(renameFile(imagepath)) + // .stream(inputStream, resizedImage.length, -1) + // .contentType("image/jpeg") + // .build() + // ); diff --git a/middlewares/1.firsttime_deploy_waverless.py b/middlewares/1.firsttime_deploy_waverless.py index 1cbf61e..f8c1655 100644 --- a/middlewares/1.firsttime_deploy_waverless.py +++ b/middlewares/1.firsttime_deploy_waverless.py @@ -3,7 +3,7 @@ import pylib os.chdir(CUR_FDIR) -pylib.os_system_sure(f"telego cmd --cmd deploy/bin_waverless2/prepare") +pylib.os_system_sure(f"telego cmd --cmd deploy/bin_waverless/prepare") # pylib.os_system_sure(f"telego cmd --cmd deploy/bin_waverless2/upload") pylib.os_system_sure(f"telego cmd --cmd deploy/dist_waverless/prepare") diff --git a/middlewares/2.update_waverless_bin.py b/middlewares/2.update_waverless_bin.py index fa1f541..4dde3ee 100644 --- a/middlewares/2.update_waverless_bin.py +++ b/middlewares/2.update_waverless_bin.py @@ -6,7 +6,7 @@ pylib.os_system(f"rm -rf waverless/bin_waverless2/prepare_cache/waverless_amd64") pylib.os_system(f"rm -rf waverless/bin_waverless2/prepare_cache/waverless_entry_amd64") -pylib.os_system_sure(f"telego cmd --cmd deploy/bin_waverless2/prepare") -pylib.os_system_sure(f"telego cmd --cmd deploy/bin_waverless2/upload") +pylib.os_system_sure(f"telego cmd --cmd deploy/bin_waverless/prepare") +pylib.os_system_sure(f"telego cmd --cmd deploy/bin_waverless/upload") diff --git a/middlewares/cluster_config.yml b/middlewares/cluster_config.yml index d9f5853..5937522 100644 --- a/middlewares/cluster_config.yml +++ b/middlewares/cluster_config.yml @@ -1,12 +1,14 @@ -# lab1: -# ip: 192.168.31.162 -# is_master: -# lab2: -# ip: 192.168.31.87 +# according to waverless/scripts/telego/dist/deployment.yml + +lab1: + ip: 192.168.31.162:2501 + is_master: +lab2: + ip: 192.168.31.87:2501 -# lab3: -# ip: 192.168.31.96 -# is_master: +lab3: + ip: 192.168.31.96:2501 + # is_master: # lab7: # ip: 192.168.31.89 @@ -21,8 +23,8 @@ # ip: 192.168.31.138 # lab12: # ip: 192.168.31.171 -master: - ip: 127.0.0.1 - is_master: -worker: - ip: 127.0.0.1 \ No newline at end of file +# master: +# ip: 127.0.0.1 +# is_master: +# worker: +# ip: 127.0.0.1 \ No newline at end of file diff --git a/middlewares/waverless/3.add_func.py b/middlewares/waverless/3.add_func.py index 7143a22..ad592ce 100644 --- a/middlewares/waverless/3.add_func.py +++ b/middlewares/waverless/3.add_func.py @@ -7,7 +7,27 @@ CUR_FPATH = os.path.abspath(__file__) CUR_FDIR = os.path.dirname(CUR_FPATH) # chdir to the directory of this script + + +def run_cmd_with_res(cmd): + print(f"执行命令:{cmd}") + result = os.popen(cmd) + # print(f"执行结果:{result.read()}") + return result.read() + + +import sys +if len(sys.argv) !=4: + print("Usage: python 3.add_func.py ") + exit(1) +demo_app=sys.argv[1] +rename_sub=sys.argv[2] +cluster_config_path=sys.argv[3] +cluster_config_path=os.path.abspath(cluster_config_path) + +# before chdir, we transform the cluster_config_path to absolute path os.chdir(CUR_FDIR) +################################################################################################# class FunctionContainer: pass def load_functions_into_object(file_path, obj): @@ -27,23 +47,8 @@ def load_functions_into_object(file_path, obj): ################################################################################################# - -def run_cmd_with_res(cmd): - print(f"执行命令:{cmd}") - result = os.popen(cmd) - # print(f"执行结果:{result.read()}") - return result.read() - - -import sys -if len(sys.argv) !=3: - print("Usage: python 3.add_func.py ") - exit(1) -demo_app=sys.argv[1] -rename_sub=sys.argv[2] - # targetname=sys.argv[2] -srcyaml=pylib.read_yaml("../cluster_config.yml") +srcyaml=pylib.read_yaml(cluster_config_path) first_worker_ip="" for n in srcyaml: if "is_master" not in srcyaml[n]: @@ -54,9 +59,13 @@ def run_cmd_with_res(cmd): os.chdir(f"../../demos") # pylib.os_system_sure(f"python3 scripts/1.gen_waverless_app.py {demo_app}") def upload_app(appname,rename): - appdir=f"scripts/waverless/{appname}/pack" + abssrc=os.path.abspath(f"scripts/waverless/{appname}/target/{appname}-1.0-SNAPSHOT-jar-with-dependencies.jar") + appdir=os.path.abspath(f"scripts/waverless/{appname}/pack") + target=os.path.abspath(f"scripts/waverless/{appname}/pack/app.jar") + print(f"copying {abssrc} to {target}") + # appdir=f"scripts/waverless/{appname}/pack" # 复制 JAR 文件到应用包 - os.system(f"cp ../demos/{appname}/target/{appname}-1.0-SNAPSHOT-jar-with-dependencies.jar {appdir}/app.jar") + os.system(f"cp {abssrc} {target}") os.chdir(appdir) @@ -64,6 +73,7 @@ def upload_app(appname,rename): entries_concat=" ".join(entries) print(f"{appdir} contains {entries_concat}") + print(f"zipping app pack: {entries_concat} to {rename}.zip") os.system(f"zip -r {rename}.zip {entries_concat}") os.system(f"mv {rename}.zip {CUR_FDIR}") os.chdir(CUR_FDIR) @@ -73,8 +83,9 @@ def upload_app(appname,rename): f= open(filepath, 'rb') files.append((rename, (filepath.split('/')[-1], f, 'application/zip'))) + print(f"uploading {filepath} to {first_worker_ip}") try: - response = requests.post(f'http://{first_worker_ip}:2501/appmgmt/upload_app', files=files) + response = requests.post(f'http://{first_worker_ip}/appmgmt/upload_app', files=files) print(response.status_code, response.text) except requests.exceptions.RequestException as e: print(f"An error occurred: {e}")