├── .cargo └── config.toml ├── .clang-format ├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── pull_request_template.md └── workflows │ ├── build-mrpc.yml │ ├── build-phoenix.yml │ ├── cc_bot.yml │ ├── mdbook.yml │ └── ping_reviewers.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── Makefile ├── Makefile.toml ├── README.md ├── benchmark ├── Cargo.toml ├── README.md ├── benchmark │ ├── alltoall-3w-1mb.toml │ ├── hotel_reservation │ │ └── hotel_reservation.toml │ ├── masstree_analytics │ │ ├── workload_1.toml │ │ ├── workload_2.toml │ │ └── workload_mp.toml │ ├── rpc_bench_latency │ │ ├── rpc_bench_latency_1024b.toml │ │ ├── rpc_bench_latency_128b.toml │ │ ├── rpc_bench_latency_256b.toml │ │ ├── rpc_bench_latency_512b.toml │ │ └── rpc_bench_latency_64b.toml │ ├── rpc_bench_plus.toml │ ├── rpc_bench_rate │ │ ├── rpc_bench_tput_32b_1c.toml │ │ ├── rpc_bench_tput_32b_2c.toml │ │ ├── rpc_bench_tput_32b_4c.toml │ │ └── rpc_bench_tput_32b_8c.toml │ ├── rpc_bench_tput │ │ ├── rpc_bench_tput_128b.toml │ │ ├── rpc_bench_tput_128kb.toml │ │ ├── rpc_bench_tput_1mb.toml │ │ ├── rpc_bench_tput_2kb.toml │ │ ├── rpc_bench_tput_2mb.toml │ │ ├── rpc_bench_tput_32b.toml │ │ ├── rpc_bench_tput_32kb.toml │ │ ├── rpc_bench_tput_4kb.toml │ │ ├── rpc_bench_tput_512b.toml │ │ ├── rpc_bench_tput_512kb.toml │ │ ├── rpc_bench_tput_8kb.toml │ │ └── rpc_bench_tput_8mb.toml │ ├── rpc_echo.toml │ ├── send_bw-64kb.toml │ ├── write_bw-1mb.toml │ ├── write_bw-4kb.toml │ ├── write_bw-64kb.toml │ ├── write_lat-32b.toml │ └── write_tput │ │ ├── write_tput-32b-1c-1s-8q.toml │ │ ├── write_tput-32b-4c-1s-8q.toml │ │ ├── write_tput-32b-4c-4s-8q.toml │ │ ├── write_tput-32b-8c-8s-8q.toml │ │ ├── write_tput-32b-8p.toml │ │ └── write_tput-32b.toml ├── config.toml └── src │ ├── line_reader.rs │ ├── main.rs │ └── tee.rs ├── build.sh ├── cmake └── Finddpdk.cmake ├── docker ├── Dockerfile └── build.sh ├── engine-api.txt ├── eval ├── README.md ├── hotel-services │ ├── analyze.py │ ├── collect.py │ ├── config.json │ ├── config.toml │ ├── docker-compose-geo.yml │ ├── docker-compose-profile.yml │ ├── docker-compose-rate.yml │ ├── hotel_services.toml │ ├── launch_phoenix.toml │ ├── phoenix.toml │ ├── start_containers.sh │ ├── start_phoenix.sh │ ├── start_service.sh │ └── stop_containers.sh ├── micro-bench │ ├── bandwidth │ │ ├── README.md │ │ ├── collect.py │ │ ├── config.toml │ │ ├── launch_phoenix.toml │ │ ├── phoenix.toml │ │ ├── start_phoenix.sh │ │ ├── start_traffic_rdma.sh │ │ └── start_traffic_tcp.sh │ └── rate │ │ ├── README.md │ │ ├── collect.py │ │ ├── config.toml │ │ ├── launch_phoenix.toml │ │ ├── phoenix.toml │ │ ├── start_phoenix.sh │ │ ├── start_traffic_rdma.sh │ │ └── start_traffic_tcp.sh ├── policy │ ├── chain │ │ ├── phase1 │ │ │ ├── logging_attach.toml │ │ │ ├── ratelimit_attach.toml │ │ │ └── receiver_attach.toml │ │ ├── phase2 │ │ │ ├── receiver_detach.toml │ │ │ └── sender_attach.toml │ │ └── phase3 │ │ │ ├── logging_detach.toml │ │ │ ├── ratelimit_detach.toml │ │ │ └── sender_detach.toml │ ├── hello-acl-receiver │ │ ├── attach.toml │ │ └── detach.toml │ ├── hotel-acl │ │ ├── README.md │ │ ├── attach.toml │ │ ├── attach_tcp.toml │ │ ├── collect.py │ │ ├── config.toml │ │ ├── detach.toml │ │ ├── detach_tcp.toml │ │ ├── hotel_reservation.toml │ │ ├── launch_phoenix.toml │ │ ├── phoenix.toml │ │ ├── start_phoenix.sh │ │ └── start_traffic.sh │ ├── logging │ │ ├── attach.toml │ │ └── detach.toml │ ├── null │ │ ├── README.md │ │ ├── attach.toml │ │ ├── attach_policy.py │ │ ├── attach_policy.sh │ │ ├── config.toml │ │ ├── detach.toml │ │ ├── launch_phoenix.toml │ │ ├── phoenix.toml │ │ ├── rpc_bench_latency_64b.toml │ │ ├── run_policy.py │ │ ├── start_phoenix.sh │ │ ├── start_traffic_rdma.sh │ │ └── start_traffic_tcp.sh │ ├── qos │ │ ├── README.md │ │ ├── attach_high_priority.toml │ │ ├── attach_low_priority.toml │ │ ├── brusty_bandwidth.toml │ │ ├── brusty_latency.toml │ │ ├── config.toml │ │ ├── launch_phoenix.toml │ │ ├── phoenix_client.toml │ │ ├── phoenix_server.toml │ │ ├── run_qos.py │ │ └── start_phoenix.sh │ └── ratelimit │ │ ├── README.md │ │ ├── attach.toml │ │ ├── collect.py │ │ ├── config.toml │ │ ├── detach.toml │ │ ├── launch_phoenix.toml │ │ ├── phoenix.toml │ │ ├── rpc_bench_tput_32b.toml │ │ ├── run_policy.py │ │ └── start_phoenix.sh └── upgrade │ └── rpc_adapter.toml ├── examples ├── alltoall │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── bench │ ├── Cargo.toml │ └── src │ │ ├── bench_bw.rs │ │ ├── bench_lat.rs │ │ ├── lib.rs │ │ ├── read_bw.rs │ │ ├── read_lat.rs │ │ ├── send_bw.rs │ │ ├── send_lat.rs │ │ ├── util.rs │ │ ├── write_bw.rs │ │ └── write_lat.rs ├── hello │ ├── Cargo.toml │ └── src │ │ ├── receiver.rs │ │ └── sender.rs ├── send_bw │ ├── Cargo.toml │ └── src │ │ └── main.rs └── send_lat │ ├── Cargo.toml │ └── src │ └── main.rs ├── experimental ├── README.md └── mrpc │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── Makefile.toml │ ├── README.md │ ├── examples │ ├── hotel_microservices │ │ ├── Cargo.toml │ │ ├── build.rs │ │ └── src │ │ │ ├── config.rs │ │ │ ├── frontend │ │ │ ├── main.rs │ │ │ └── server.rs │ │ │ ├── geo │ │ │ ├── db.rs │ │ │ ├── main.rs │ │ │ └── server.rs │ │ │ ├── latency_bench │ │ │ ├── client.rs │ │ │ └── server.rs │ │ │ ├── logging.rs │ │ │ ├── profile │ │ │ ├── db.rs │ │ │ ├── main.rs │ │ │ └── server.rs │ │ │ ├── rate │ │ │ ├── db.rs │ │ │ ├── main.rs │ │ │ └── server.rs │ │ │ ├── search │ │ │ ├── main.rs │ │ │ └── server.rs │ │ │ └── tracer.rs │ ├── hotel_reservation │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ └── src │ │ │ ├── client.rs │ │ │ └── server.rs │ ├── load_balancer │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ └── src │ │ │ ├── client.rs │ │ │ └── server.rs │ ├── masstree_analytics │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ ├── libmt_index │ │ │ ├── CMakeLists.txt │ │ │ ├── capi.cc │ │ │ ├── capi.h │ │ │ ├── mt_index_api.cc │ │ │ ├── mt_index_api.h │ │ │ └── test │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── test_mt_index.cc │ │ └── src │ │ │ ├── client.rs │ │ │ ├── ffi.rs │ │ │ ├── latency.rs │ │ │ ├── lib.rs │ │ │ ├── logging.rs │ │ │ ├── mt_index.rs │ │ │ └── server.rs │ ├── proto │ │ ├── hotel_microservices │ │ │ ├── geo.proto │ │ │ ├── profile.proto │ │ │ ├── rate.proto │ │ │ └── search.proto │ │ ├── masstree_analytics │ │ │ └── masstree_analytics.proto │ │ ├── reservation │ │ │ └── reservation.proto │ │ ├── rpc_hello │ │ │ └── rpc_hello.proto │ │ └── rpc_plus │ │ │ └── rpc_plus.proto │ ├── rpc_bench │ │ ├── Cargo.toml │ │ ├── build.rs │ │ └── src │ │ │ ├── bench_app.rs │ │ │ ├── brusty_client.rs │ │ │ ├── client.rs │ │ │ └── server.rs │ ├── rpc_bench_plus │ │ ├── Cargo.toml │ │ ├── build.rs │ │ └── src │ │ │ ├── bench_app.rs │ │ │ ├── client.rs │ │ │ └── server.rs │ └── rpc_echo │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ └── src │ │ ├── client.rs │ │ ├── client2.rs │ │ ├── frontend.rs │ │ └── server.rs │ ├── load-mrpc-plugins.toml │ ├── mrpc-build │ ├── Cargo.toml │ └── src │ │ ├── attribute.rs │ │ ├── client.rs │ │ ├── lib.rs │ │ ├── prost.rs │ │ └── server.rs │ ├── mrpc-derive │ ├── Cargo.toml │ └── src │ │ ├── field │ │ ├── message.rs │ │ ├── mod.rs │ │ └── scalar.rs │ │ └── lib.rs │ ├── mrpc-marshal │ ├── Cargo.toml │ └── src │ │ ├── emplacement │ │ ├── bytes.rs │ │ ├── message.rs │ │ ├── mod.rs │ │ ├── numeric.rs │ │ └── string.rs │ │ ├── lib.rs │ │ └── shadow │ │ ├── mod.rs │ │ ├── raw_vec.rs │ │ ├── string.rs │ │ └── vec.rs │ ├── phoenix-api │ ├── load_balancer │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── control_plane.rs │ │ │ └── lib.rs │ ├── mrpc │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── cmd.rs │ │ │ ├── control_plane.rs │ │ │ ├── dp.rs │ │ │ └── lib.rs │ ├── mrpclb │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── cmd.rs │ │ │ ├── control_plane.rs │ │ │ ├── dp.rs │ │ │ └── lib.rs │ ├── policy │ │ ├── hello-acl-receiver │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── control_plane.rs │ │ │ │ └── lib.rs │ │ ├── hello-acl-sender │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── control_plane.rs │ │ │ │ └── lib.rs │ │ ├── hotel-acl │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── control_plane.rs │ │ │ │ └── lib.rs │ │ ├── logging │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── control_plane.rs │ │ │ │ └── lib.rs │ │ ├── null │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── control_plane.rs │ │ │ │ └── lib.rs │ │ ├── qos │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── control_plane.rs │ │ │ │ └── lib.rs │ │ └── ratelimit │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ ├── control_plane.rs │ │ │ └── lib.rs │ ├── rpc_adapter │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── control_plane.rs │ │ │ └── lib.rs │ └── tcp_rpc_adapter │ │ ├── Cargo.toml │ │ └── src │ │ ├── control_plane.rs │ │ └── lib.rs │ ├── plugin │ ├── load_balancer │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── engine.rs │ │ │ ├── lib.rs │ │ │ └── module.rs │ ├── mrpc │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── builder │ │ │ ├── cache.rs │ │ │ ├── compiler │ │ │ │ ├── code_generator.rs │ │ │ │ ├── mod.rs │ │ │ │ └── template │ │ │ │ │ └── Cargo.toml │ │ │ ├── mod.rs │ │ │ └── prost │ │ │ │ ├── mod.rs │ │ │ │ ├── prost.rs │ │ │ │ └── service.rs │ │ │ ├── config.rs │ │ │ ├── engine.rs │ │ │ ├── lib.rs │ │ │ ├── module.rs │ │ │ ├── state.rs │ │ │ └── unpack.rs │ ├── mrpclb │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── builder │ │ │ ├── cache.rs │ │ │ ├── compiler │ │ │ │ ├── code_generator.rs │ │ │ │ ├── mod.rs │ │ │ │ └── template │ │ │ │ │ └── Cargo.toml │ │ │ ├── mod.rs │ │ │ └── prost │ │ │ │ ├── mod.rs │ │ │ │ ├── prost.rs │ │ │ │ └── service.rs │ │ │ ├── config.rs │ │ │ ├── engine.rs │ │ │ ├── lib.rs │ │ │ ├── module.rs │ │ │ ├── state.rs │ │ │ └── unpack.rs │ ├── policy │ │ ├── hello-acl-receiver │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── config.rs │ │ │ │ ├── engine.rs │ │ │ │ ├── lib.rs │ │ │ │ ├── module.rs │ │ │ │ └── rpc_hello.rs │ │ ├── hello-acl-sender │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── config.rs │ │ │ │ ├── engine.rs │ │ │ │ ├── lib.rs │ │ │ │ ├── module.rs │ │ │ │ └── rpc_hello.rs │ │ ├── hotel-acl │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── config.rs │ │ │ │ ├── engine.rs │ │ │ │ ├── lib.rs │ │ │ │ ├── module.rs │ │ │ │ └── reservation.rs │ │ ├── logging │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── config.rs │ │ │ │ ├── engine.rs │ │ │ │ ├── lib.rs │ │ │ │ └── module.rs │ │ ├── null │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── config.rs │ │ │ │ ├── engine.rs │ │ │ │ ├── lib.rs │ │ │ │ └── module.rs │ │ ├── qos │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── config.rs │ │ │ │ ├── engine.rs │ │ │ │ ├── lib.rs │ │ │ │ └── module.rs │ │ └── ratelimit │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ ├── config.rs │ │ │ ├── engine.rs │ │ │ ├── lib.rs │ │ │ └── module.rs │ ├── rpc_adapter │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── acceptor │ │ │ ├── engine.rs │ │ │ └── mod.rs │ │ │ ├── config.rs │ │ │ ├── engine.rs │ │ │ ├── lib.rs │ │ │ ├── module.rs │ │ │ ├── pool.rs │ │ │ ├── serialization.rs │ │ │ ├── state.rs │ │ │ └── ulib │ │ │ ├── fp.rs │ │ │ ├── mod.rs │ │ │ ├── ucm.rs │ │ │ └── uverbs.rs │ └── tcp_rpc_adapter │ │ ├── Cargo.toml │ │ └── src │ │ ├── engine.rs │ │ ├── lib.rs │ │ ├── module.rs │ │ ├── pool.rs │ │ ├── serialization.rs │ │ └── state.rs │ ├── rpc.svg │ ├── rust-toolchain │ └── src │ ├── codegen.rs │ ├── lib.rs │ ├── macros.rs │ ├── rheap.rs │ ├── rref.rs │ ├── sched.rs │ ├── status.rs │ ├── stub │ ├── client.rs │ ├── conn.rs │ ├── local_server.rs │ ├── mod.rs │ ├── pending.rs │ ├── reactor.rs │ ├── reply_cache.rs │ ├── server.rs │ └── service.rs │ ├── timing.rs │ └── wref.rs ├── mdbook ├── .gitignore ├── README.md ├── book.toml └── src │ ├── SUMMARY.md │ ├── introduction.md │ ├── mrpc-ffi │ ├── cpp-ffi.md │ └── outline.md │ └── tutorials │ ├── chain.md │ ├── outline.md │ ├── policy-management.md │ └── working-with-mrpc-library.md ├── phoenix-logo-red-black.png ├── phoenix.toml ├── rust-toolchain ├── rustfmt.toml ├── scripts ├── build_debug.sh ├── build_release.sh ├── check-git-clang-format.sh ├── clippy.sh ├── config_eval.sh ├── count_loc.sh ├── cpu_performance.sh ├── create_sysroot.sh ├── deploy_plugins.sh ├── format.sh ├── git_utils.py ├── github_cc_reviewers.py ├── killall.sh ├── locate_symbol.sh └── ping_reviewers.py ├── src ├── experimental │ ├── CMakeLists.txt │ ├── Cargo.toml │ ├── examples │ │ ├── bench_atomicring_mpsc.rs │ │ ├── bench_bw.cc │ │ ├── bench_crossbeam_mpsc.rs │ │ ├── bench_crossbeam_mpsc_round_trip.rs │ │ ├── bench_flume_mpsc.rs │ │ ├── bench_flume_mpsc_round_trip.rs │ │ ├── bench_hashmap.rs │ │ ├── bench_lamport_spsc.cc │ │ ├── bench_lat.cc │ │ ├── bench_read_bw.h │ │ ├── bench_read_lat.h │ │ ├── bench_ringbuf_spsc.rs │ │ ├── bench_ringbuffer_spsc.rs │ │ ├── bench_ringbuffer_spsc_round_trip.rs │ │ ├── bench_send_bw.h │ │ ├── bench_send_lat.h │ │ ├── bench_shmem_ipc.rs │ │ ├── bench_shmem_ipc_sync.rs │ │ ├── bench_std_mpsc.rs │ │ ├── bench_timestamp.c │ │ ├── bench_timestamp.rs │ │ ├── bench_tokio_mpsc.rs │ │ ├── bench_tokio_mpsc_round_trip.rs │ │ ├── bench_util.h │ │ ├── bench_write_bw.h │ │ ├── bench_write_lat.h │ │ ├── get_clock.cc │ │ ├── get_clock.h │ │ ├── locate_symbol.rs │ │ ├── mini_salloc.rs │ │ ├── parse_config.rs │ │ ├── socket_lat_receiver.rs │ │ ├── socket_lat_sender.rs │ │ ├── socket_poll.rs │ │ ├── test_dispatch_codegen.rs │ │ └── test_domain_socket.rs │ ├── include │ │ └── prism │ │ │ └── logging.h │ ├── proto │ │ └── rpc_hello.proto │ ├── src │ │ ├── aligned_alloc.rs │ │ ├── engine_draft.rs │ │ ├── interface_draft.rs │ │ ├── ipc.rs │ │ ├── ipc_deprecated.rs │ │ ├── lib.rs │ │ ├── mmap_aligned.rs │ │ ├── regmr.rs │ │ ├── ringbuffer.rs │ │ ├── shm.rs │ │ └── shmalloc.rs │ └── tests │ │ └── ringbuffer.rs ├── ipc │ ├── Cargo.toml │ └── src │ │ ├── channel │ │ ├── flavors │ │ │ ├── concurrent.rs │ │ │ ├── mod.rs │ │ │ └── sequential.rs │ │ └── mod.rs │ │ ├── control.rs │ │ ├── customer.rs │ │ ├── ipc_channel.rs │ │ ├── lib.rs │ │ ├── service.rs │ │ ├── shmem_ipc.rs │ │ ├── shmobj.rs │ │ └── unix.rs ├── phoenix-common-workspace │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── phoenix-syscalls │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── transport │ │ ├── cm.rs │ │ ├── fp.rs │ │ ├── mod.rs │ │ └── verbs.rs ├── phoenix_common │ ├── Cargo.toml │ └── src │ │ ├── addon.rs │ │ ├── engine │ │ ├── datapath │ │ │ ├── message.rs │ │ │ ├── meta_pool.rs │ │ │ ├── mod.rs │ │ │ └── node.rs │ │ ├── decompose.rs │ │ ├── future.rs │ │ └── mod.rs │ │ ├── envelop.rs │ │ ├── lib.rs │ │ ├── local_resource.rs │ │ ├── module.rs │ │ ├── page_padded.rs │ │ ├── resource.rs │ │ ├── state_mgr.rs │ │ └── storage.rs ├── phoenixctl │ ├── Cargo.toml │ └── src │ │ └── bin │ │ ├── addonctl.rs │ │ ├── list.rs │ │ ├── listconn.rs │ │ ├── qosctl.rs │ │ ├── ratelimitctl.rs │ │ └── upgrade.rs ├── phoenixos │ ├── Cargo.toml │ └── src │ │ ├── config.rs │ │ ├── control.rs │ │ ├── dependency.rs │ │ ├── linker │ │ ├── initfini.rs │ │ ├── mod.rs │ │ ├── module.rs │ │ ├── relocation.rs │ │ ├── section.rs │ │ ├── symbol.rs │ │ └── tls.rs │ │ ├── logging.rs │ │ ├── main.rs │ │ ├── plugin.rs │ │ ├── plugin_mgr.rs │ │ └── runtime │ │ ├── affinity.rs │ │ ├── container.rs │ │ ├── executor.rs │ │ ├── graph.rs │ │ ├── group.rs │ │ ├── lb.rs │ │ ├── manager.rs │ │ ├── mod.rs │ │ └── upgrade.rs ├── plugin │ ├── salloc │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── config.rs │ │ │ ├── engine.rs │ │ │ ├── lib.rs │ │ │ ├── module.rs │ │ │ ├── region.rs │ │ │ └── state.rs │ ├── scheduler │ │ ├── engine.rs │ │ ├── mod.rs │ │ ├── module.rs │ │ └── stacked_buffer.rs │ ├── transport-rdma │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── cm │ │ │ ├── engine.rs │ │ │ └── mod.rs │ │ │ ├── config.rs │ │ │ ├── engine.rs │ │ │ ├── lib.rs │ │ │ ├── module.rs │ │ │ ├── ops.rs │ │ │ └── state.rs │ └── transport-tcp │ │ ├── Cargo.toml │ │ └── src │ │ ├── config.rs │ │ ├── engine.rs │ │ ├── lib.rs │ │ ├── module.rs │ │ ├── mr.rs │ │ ├── ops.rs │ │ └── state.rs ├── shm │ ├── Cargo.toml │ ├── shmalloc │ │ ├── Cargo.toml │ │ ├── README.md │ │ └── src │ │ │ ├── backend.rs │ │ │ ├── gc.rs │ │ │ ├── lib.rs │ │ │ └── wheap.rs │ └── src │ │ ├── alloc │ │ ├── mod.rs │ │ └── system.rs │ │ ├── boxed.rs │ │ ├── collections │ │ └── mod.rs │ │ ├── lib.rs │ │ ├── ptr │ │ ├── mod.rs │ │ ├── shm_non_null.rs │ │ └── shmptr.rs │ │ ├── raw_vec.rs │ │ ├── string.rs │ │ └── vec.rs ├── slabmalloc │ ├── .github │ │ └── dependabot.yml │ ├── .gitignore │ ├── .travis.yml │ ├── Cargo.toml │ ├── LICENSE.md │ ├── README.md │ ├── examples │ │ └── global_alloc.rs │ └── src │ │ ├── lib.rs │ │ ├── pages.rs │ │ ├── pool.rs │ │ ├── sc.rs │ │ ├── tests.rs │ │ └── zone.rs └── utils │ ├── Cargo.toml │ └── src │ ├── bounded_vec.rs │ ├── cmd_helper.rs │ ├── lib.rs │ └── timer.rs └── tools └── phoenix_cargo ├── .gitignore ├── Cargo.toml └── src └── main.rs /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [alias] 2 | # command aliases 3 | rr = "run --release" 4 | build-plan = "build --build-plan -Z unstable-options" 5 | 6 | [env] 7 | RUST_BACKTRACE = "1" 8 | 9 | [build] 10 | rustflags = [ 11 | # "-C", "codegen-units=1", 12 | 13 | # link all symbols in dependent crates even if they are not actually used (moved to phoenix/build.rs) 14 | "-C", "link-dead-code", 15 | 16 | # employ no restriction on the addresses of the symbols and sizes of sections, 17 | # as more and more plugins loaded, 2GB code and data size might be too restricted. 18 | "-C", "code-model=large", 19 | ] 20 | # disable incremental compilation to ensure cargo prints inforamtion about every crates 21 | # incremental = false 22 | 23 | [unstable] 24 | # -Zbinary-dep-depinfo allows us to track dependencies of each rlib 25 | binary-dep-depinfo = true 26 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | # Run manually to reformat a file: 2 | # clang-format -i --style=file 3 | BasedOnStyle: Google 4 | DerivePointerAlignment: false 5 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/rust:0-1-bullseye 2 | 3 | RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 4 | && apt install -y libclang-dev libnuma-dev librdmacm-dev libibverbs-dev protobuf-compiler 5 | 6 | RUN cargo install cargo-make -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/rust 3 | { 4 | "name": "Phoenix", 5 | "build": { "dockerfile": "Dockerfile" }, 6 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 7 | // "image": "mcr.microsoft.com/devcontainers/rust:0-1-bullseye" 8 | 9 | // Configure tool-specific properties. 10 | "customizations": { 11 | "vscode": { 12 | "extensions": [ 13 | "rust-lang.rust-analyzer", 14 | "tamasfe.even-better-toml", 15 | "ms-vscode.cpptools" 16 | ] 17 | } 18 | }, 19 | 20 | // Features to add to the dev container. More info: https://containers.dev/features. 21 | // "features": {}, 22 | 23 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 24 | "forwardPorts": [3000], 25 | 26 | // Use 'postCreateCommand' to run commands after the container is created. 27 | "postCreateCommand": "rustc --version", 28 | 29 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 30 | "remoteUser": "root" 31 | } 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ## Why are these changes needed? 6 | 7 | 8 | 9 | ## Related issue number 10 | 11 | 12 | 13 | ## Checks 14 | 15 | - [ ] I've run `scripts/clippy.sh` to lint the changes in this PR. 16 | - [ ] I've included any doc changes. 17 | - Testing Strategy 18 | - [ ] Release tests 19 | - [ ] This PR is not tested :( 20 | -------------------------------------------------------------------------------- /.github/workflows/mdbook.yml: -------------------------------------------------------------------------------- 1 | name: Build Documentation 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-22.04 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.ref }} 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Setup mdBook 16 | uses: peaceiris/actions-mdbook@v1 17 | with: 18 | mdbook-version: 'latest' 19 | 20 | - run: mdbook build mdbook 21 | 22 | - name: Deploy 23 | uses: peaceiris/actions-gh-pages@v3 24 | if: ${{ github.ref == 'refs/heads/main' }} 25 | with: 26 | deploy_key: ${{ secrets.DEPLOY_KEY_DOC }} 27 | external_repository: phoenix-dataplane/phoenix-dataplane.github.io 28 | publish_branch: main 29 | publish_dir: mdbook/book 30 | force_orphan: true 31 | -------------------------------------------------------------------------------- /.github/workflows/ping_reviewers.yml: -------------------------------------------------------------------------------- 1 | name: Ping Reviewers 2 | on: 3 | schedule: 4 | - cron: "0/15 * * * *" 5 | workflow_dispatch: 6 | 7 | concurrency: 8 | group: ping 9 | cancel-in-progress: true 10 | 11 | jobs: 12 | ping: 13 | if: github.repository == 'phoenix-dataplane/phoenix' 14 | runs-on: ubuntu-22.04 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Ping reviewers 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | run: | 21 | set -eux 22 | python scripts/ping_reviewers.py --wait-time-minutes 360 || echo failed 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | phoenix_compile_log.txt 2 | 3 | # Prerequisites 4 | *.d 5 | 6 | # Compiled Object files 7 | *.slo 8 | *.lo 9 | *.o 10 | *.obj 11 | 12 | # Precompiled Headers 13 | *.gch 14 | *.pch 15 | 16 | # Compiled Dynamic libraries 17 | *.so 18 | *.dylib 19 | *.dll 20 | 21 | # Fortran module files 22 | *.mod 23 | *.smod 24 | 25 | # Compiled Static libraries 26 | *.lai 27 | *.la 28 | *.a 29 | *.lib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | 36 | 37 | # build 38 | build/ 39 | # clangd 40 | .clangd/ 41 | .cache/clangd/ 42 | compile_commands.json 43 | 44 | # vim session file 45 | Session.vim 46 | # vscode 47 | *.workspace 48 | *.code-workspace 49 | .vscode/ 50 | 51 | 52 | # Added by cargo 53 | 54 | /target 55 | 56 | # macOS 57 | # General 58 | .DS_Store 59 | .AppleDouble 60 | .LSOverride 61 | 62 | # Icon must end with two \r 63 | Icon 64 | 65 | 66 | # Thumbnails 67 | ._* 68 | 69 | # Jetbrains IDE 70 | .idea/ 71 | cmake-build-*/ 72 | 73 | # Private folder for development 74 | /_private 75 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "experimental/mrpc/examples/masstree_analytics/libmt_index/masstree-beta"] 2 | path = experimental/mrpc/examples/masstree_analytics/libmt_index/masstree-beta 3 | url = https://github.com/anujkaliaiitd/masstree-beta.git 4 | [submodule "experimental/mrpc/3rdparty/prost"] 5 | path = experimental/mrpc/3rdparty/prost 6 | url = https://github.com/phoenix-dataplane/prost.git 7 | branch = mrpc-refactor 8 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # CMakeLists files in this project can 2 | # refer to the root source directory of the project as ${HELLO_SOURCE_DIR} and 3 | # to the root binary directory of the project as ${HELLO_BINARY_DIR}. 4 | cmake_minimum_required(VERSION 3.0) 5 | project(phoenix) 6 | 7 | # for clang's compile_commands.json 8 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 9 | set(CMAKE_CXX_COMPILER_ID "GNU") 10 | set(CMAKE_CXX_STANDARD 17) 11 | 12 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 13 | 14 | # add_subdirectory(src/vendor/googlelog) 15 | # include_directories(${GLOG_INCLUDE_DIRS}) 16 | # link_directories(${GLOG_LINK_DIRS}) 17 | 18 | # find_package(dpdk REQUIRED) 19 | 20 | # Compile experimental code 21 | add_subdirectory(src/experimental) 22 | 23 | # masstree_analytics 24 | add_subdirectory(src/phoenix_examples/masstree_analytics/libmt_index) 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # A dummy Makefile that forwards all arguments to cargo-make. 2 | .PHONY: all % 3 | 4 | all: 5 | @cargo make $(ARGS) 6 | 7 | %: 8 | @cargo make $@ $(ARGS) 9 | -------------------------------------------------------------------------------- /benchmark/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "benchmark" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | ansi_term = "0.12.1" 10 | anyhow = "1.0.57" 11 | bytes = "1.1.0" 12 | chrono = "0.4.19" 13 | env_logger = "0.9.0" 14 | lazy_static = "1.4.0" 15 | log = "0.4.17" 16 | nix = { version = "0.24.1", default-features = false, features = ["signal"] } 17 | serde = { version = "1.0.137", features = ["derive"] } 18 | shellexpand = "2.1.0" 19 | structopt = "0.3.26" 20 | tokio-anyfd = "0.2.0" 21 | toml = "0.5.9" 22 | walkdir = "2.3.2" 23 | 24 | [[bin]] 25 | name = "launcher" 26 | path = "src/main.rs" 27 | -------------------------------------------------------------------------------- /benchmark/benchmark/alltoall-3w-1mb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/alltoall-3w-1mb" 2 | description = "Run bandwidth benchmark for all-to-all traffic pattern" 3 | group = "alltoall" 4 | 5 | [[worker]] 6 | host = "danyang-06" 7 | bin = "alltoall" 8 | args = "st --hosts rdma0.danyang-06,rdma0.danyang-05,rdma0.danyang-04 -m 1024000 -p 4000" 9 | dependencies = [] 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "alltoall" 14 | args = "st --hosts rdma0.danyang-06,rdma0.danyang-05,rdma0.danyang-04 -m 1024000 -p 4000" 15 | dependencies = [0] 16 | 17 | [[worker]] 18 | host = "danyang-04" 19 | bin = "alltoall" 20 | args = "st --hosts rdma0.danyang-06,rdma0.danyang-05,rdma0.danyang-04 -m 1024000 -p 4000" 21 | dependencies = [0, 1] 22 | -------------------------------------------------------------------------------- /benchmark/benchmark/hotel_reservation/hotel_reservation.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/hotel_reservation" 2 | description = "Run hotel_reservation rate test" 3 | group = "hotel_reservation" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "hotel_reservation_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "hotel_reservation_client" 14 | args = "-c rdma0.danyang-06 --concurrency 32 -D 10 -i 1" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/masstree_analytics/workload_1.toml: -------------------------------------------------------------------------------- 1 | name = "masstree_analytics/workload_1" 2 | description = "Masstree analytics workload 1" 3 | group = "masstree_analytics" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "masstree_analytics_server" 9 | args = """\ 10 | --num-keys 1000000 \ 11 | --num-server-fg-threads 14 \ 12 | --num-server-bg-threads 2 \ 13 | --server-port 5000 \ 14 | """ 15 | 16 | [[worker]] 17 | host = "danyang-05" 18 | bin = "masstree_analytics_client" 19 | args = """\ 20 | --test-ms 10000 \ 21 | --num-client-threads 8 \ 22 | --req-window 2 \ 23 | --num-keys 1000000 \ 24 | --range-size 128 \ 25 | --range-req-percent 1 \ 26 | --server-port 5000 \ 27 | --server-addr rdma0.danyang-06 \ 28 | --num-server-fg-threads 14 \ 29 | """ 30 | -------------------------------------------------------------------------------- /benchmark/benchmark/masstree_analytics/workload_2.toml: -------------------------------------------------------------------------------- 1 | name = "masstree_analytics/workload_2" 2 | description = "Masstree analytics workload 2" 3 | group = "masstree_analytics" 4 | timeout_secs = 150 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "masstree_analytics_server" 9 | args = """\ 10 | --num-keys 1000000 \ 11 | --num-server-fg-threads 8 \ 12 | --num-server-bg-threads 2 \ 13 | --server-port 5000 \ 14 | """ 15 | 16 | [[worker]] 17 | host = "danyang-05" 18 | bin = "masstree_analytics_client" 19 | args = """\ 20 | --test-ms 120000 \ 21 | --num-client-threads 8 \ 22 | --req-window 32 \ 23 | --num-keys 1000000 \ 24 | --range-size 128 \ 25 | --range-req-percent 1 \ 26 | --server-port 5000 \ 27 | --server-addr rdma0.danyang-06 \ 28 | --server-addr rdma1.danyang-06 \ 29 | --num-server-fg-threads 8 \ 30 | """ 31 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_latency/rpc_bench_latency_1024b.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_latency/rpc_bench_latency_1024b" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_latency" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 1 --req-size 1024" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_latency/rpc_bench_latency_128b.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_latency/rpc_bench_latency_128b" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_latency" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 1 --req-size 128" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_latency/rpc_bench_latency_256b.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_latency/rpc_bench_latency_256b" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_latency" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 1 --req-size 256" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_latency/rpc_bench_latency_512b.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_latency/rpc_bench_latency_512b" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_latency" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 1 --req-size 512" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_latency/rpc_bench_latency_64b.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_latency/rpc_bench_latency_64b" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_latency" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 1 --req-size 64" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_plus.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_plus" 2 | description = "Run rpc_bench_plus benchmark" 3 | group = "rpc_bench_plus" 4 | 5 | [[worker]] 6 | host = "danyang-06" 7 | bin = "rpc_bench_plus_server" 8 | args = "" 9 | 10 | [[worker]] 11 | host = "danyang-05" 12 | bin = "rpc_bench_plus_client" 13 | args = "-c rdma0.danyang-06 --concurrency 1" 14 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_rate/rpc_bench_tput_32b_1c.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_rate/rpc_bench_rate_32b_1c" 2 | description = "Small RPC rate and scalability" 3 | group = "rpc_bench_rate" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "--num-server-threads 1" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 32 -D 10 -i 1 --num-client-threads 1 --num-server-threads 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_rate/rpc_bench_tput_32b_2c.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_rate/rpc_bench_rate_32b_2c" 2 | description = "Small RPC rate and scalability" 3 | group = "rpc_bench_rate" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "--num-server-threads 2" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 -c rdma1.danyang-06 --concurrency 32 --req-size 32 -D 10 -i 1 --num-client-threads 2 --num-server-threads 2 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_rate/rpc_bench_tput_32b_4c.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_rate/rpc_bench_rate_32b_4c" 2 | description = "Small RPC rate and scalability" 3 | group = "rpc_bench_rate" 4 | timeout_secs = 25 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "--num-server-threads 4" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 -c rdma1.danyang-06 --concurrency 32 --req-size 32 -D 15 -i 1 --num-client-threads 4 --num-server-threads 4 -linfo" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_rate/rpc_bench_tput_32b_8c.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_rate/rpc_bench_rate_32b_8c" 2 | description = "Small RPC rate and scalability" 3 | group = "rpc_bench_rate" 4 | timeout_secs = 35 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "--num-server-threads 8" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 -c rdma1.danyang-06 --concurrency 32 --req-size 32 -D 25 -i 1 --num-client-threads 8 --num-server-threads 8 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_128b.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_128b" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 128 -D 10 -i 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_128kb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_128kb" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 131072 -D 10 -i 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_1mb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_1mb" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 1000000 -D 10 -i 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_2kb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_2kb" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 2048 -D 10 -i 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_2mb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_2mb" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 2097152 -D 10 -i 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_32b.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_32b" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 32 -D 10 -i 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_32kb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_32kb" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 32768 -D 10 -i 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_4kb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_2kb" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 32 --req-size 4096 -D 10 -i 1" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_512b.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_512b" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 512 -D 10 -i 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_512kb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_512kb" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 524288 -D 10 -i 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_8kb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_8kb" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 8192 -D 10 -i 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_bench_tput/rpc_bench_tput_8mb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_bench_tput/rpc_bench_tput_8mb" 2 | description = "Run rpc_bench benchmark" 3 | group = "rpc_bench_tput" 4 | timeout_secs = 15 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 8000000 -D 15 -i 1 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/rpc_echo.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/rpc_echo" 2 | description = "Run rpc_echo benchmark" 3 | group = "rpc_echo" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "" 8 | bin = "rpc_echo_server" 9 | args = "" 10 | dependencies = [] 11 | 12 | [[worker]] 13 | host = "" 14 | bin = "rpc_echo_client" 15 | args = "" 16 | dependencies = [0] 17 | -------------------------------------------------------------------------------- /benchmark/benchmark/send_bw-64kb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/send_bw-64kb" 2 | description = "Run bandwidth benchmark for send/recv" 3 | group = "send_bw" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "send_bw" 9 | args = "" 10 | dependencies = [] 11 | 12 | [[worker]] 13 | host = "danyang-05" 14 | bin = "send_bw" 15 | args = "-c rdma0.danyang-06" 16 | dependencies = [0] 17 | -------------------------------------------------------------------------------- /benchmark/benchmark/write_bw-1mb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/write_bw-1mb" 2 | description = "Run bandwidth benchmark for RDMA write" 3 | group = "write_bw" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "bench_bw" 9 | args = "write -n 10000 -s 1048576" 10 | dependencies = [] 11 | 12 | [[worker]] 13 | host = "danyang-05" 14 | bin = "bench_bw" 15 | args = "write -n 10000 -c rdma0.danyang-06 -s 1048576" 16 | dependencies = [0] 17 | -------------------------------------------------------------------------------- /benchmark/benchmark/write_bw-4kb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/write_bw-4kb" 2 | description = "Run bandwidth benchmark for RDMA write" 3 | group = "write_bw" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "bench_bw" 9 | args = "write -n 100000 -s 4096" 10 | dependencies = [] 11 | 12 | [[worker]] 13 | host = "danyang-05" 14 | bin = "bench_bw" 15 | args = "write -n 100000 -c rdma0.danyang-06 -s 4096" 16 | dependencies = [0] 17 | -------------------------------------------------------------------------------- /benchmark/benchmark/write_bw-64kb.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/write_bw-64kb" 2 | description = "Run bandwidth benchmark for RDMA write" 3 | group = "write_bw" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "bench_bw" 9 | args = "write -n 10000" 10 | dependencies = [] 11 | 12 | [[worker]] 13 | host = "danyang-05" 14 | bin = "bench_bw" 15 | args = "write -n 10000 -c rdma0.danyang-06" 16 | dependencies = [0] 17 | -------------------------------------------------------------------------------- /benchmark/benchmark/write_lat-32b.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/write_lat-32b" 2 | description = "Run latency benchmark for RDMA write" 3 | group = "write_lat" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "bench_lat" 9 | args = "write -n 10000 -s 32" 10 | dependencies = [] 11 | 12 | [[worker]] 13 | host = "danyang-05" 14 | bin = "bench_lat" 15 | args = "write -n 10000 -s 32 -c rdma0.danyang-06" 16 | dependencies = [0] 17 | -------------------------------------------------------------------------------- /benchmark/benchmark/write_tput/write_tput-32b-1c-1s-8q.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/write_tput/write_tput-32b-8c-8s-8q" 2 | description = "Run RPS benchmark for RDMA write 8 client threads and 8 server threads, each with 8 QPs" 3 | group = "write_tput" 4 | timeout_secs = 60 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "bench_bw" 9 | args = "write -n 1000000 -s 32 --port 5000 --num-qp 8 --num-client-threads 1 --num-server-threads 1" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "bench_bw" 14 | args = "write -n 1000000 -s 32 -c rdma0.danyang-06 --port 5000 --num-qp 8 --num-client-threads 1 --num-server-threads 1" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/write_tput/write_tput-32b-4c-1s-8q.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/write_tput/write_tput-32b-4c-1s-8q" 2 | description = "Run RPS benchmark for RDMA write 4 client threads and 1 server threads, each with 8 QPs" 3 | group = "write_tput" 4 | timeout_secs = 60 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "bench_bw" 9 | args = "write -n 1000000 -s 32 --port 5000 --num-qp 8 --num-client-threads 4 --num-server-threads 1" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "bench_bw" 14 | args = "write -n 1000000 -s 32 -c rdma0.danyang-06 --port 5000 --num-qp 8 --num-client-threads 4 --num-server-threads 1" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/write_tput/write_tput-32b-4c-4s-8q.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/write_tput/write_tput-32b-4c-4s-8q" 2 | description = "Run RPS benchmark for RDMA write 4 client threads and 4 server threads, each with 8 QPs" 3 | group = "write_tput" 4 | timeout_secs = 60 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "bench_bw" 9 | args = "write -n 1000000 -s 32 --port 5000 --num-qp 8 --num-client-threads 4 --num-server-threads 4" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "bench_bw" 14 | args = "write -n 1000000 -s 32 -c rdma0.danyang-06 --port 5000 --num-qp 8 --num-client-threads 4 --num-server-threads 4" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/write_tput/write_tput-32b-8c-8s-8q.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/write_tput/write_tput-32b-8c-8s-8q" 2 | description = "Run RPS benchmark for RDMA write 8 client threads and 8 server threads, each with 8 QPs" 3 | group = "write_tput" 4 | timeout_secs = 60 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "bench_bw" 9 | args = "write -n 1000000 -s 32 --port 5000 --num-qp 8 --num-client-threads 8 --num-server-threads 8" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "bench_bw" 14 | args = "write -n 1000000 -s 32 -c rdma0.danyang-06 --port 5000 --num-qp 8 --num-client-threads 8 --num-server-threads 8" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /benchmark/benchmark/write_tput/write_tput-32b.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/write_tput/write_tput-32b" 2 | description = "Run RPS benchmark for RDMA write" 3 | group = "write_tput" 4 | timeout_secs = 10 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "bench_bw" 9 | args = "write -n 10000 -s 32" 10 | dependencies = [] 11 | 12 | [[worker]] 13 | host = "danyang-05" 14 | bin = "bench_bw" 15 | args = "write -n 10000 -s 32 -c rdma0.danyang-06" 16 | dependencies = [0] 17 | -------------------------------------------------------------------------------- /benchmark/config.toml: -------------------------------------------------------------------------------- 1 | # workdir = "~/nfs/Developing/phoenix" 2 | workdir = "~/nfs/Developing/phoenix/experimental/mrpc" 3 | 4 | [env] 5 | RUST_BACKTRACE = "1" 6 | RUST_LOG_STYLE = "never" 7 | CARGO_TERM_COLOR = "never" 8 | PROTOC = "/usr/bin/protoc" 9 | PHOENIX_PREFIX = "/tmp/phoenix" 10 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | PHOENIX_COMPILE_LOG=phoenix_compile_log.txt 5 | HOST_DEP=target/host_dep 6 | 7 | # cargo build -vv -r -p phoenix_common --color=always |& tee phoenix_compile_log.txt 8 | cargo build -vv -r -p phoenix_common --color=always |& tee $PHOENIX_COMPILE_LOG 9 | 10 | cp -r target/release/deps $HOST_DEP 11 | 12 | cargo build -r --bin phoenix_cargo 13 | rm -r target/release/.fingerprint 14 | 15 | target/release/phoenix_cargo --compile-log $PHOENIX_COMPILE_LOG --host-dep $HOST_DEP -- build -v -r --target-dir target --manifest-path experimental/mrpc/Cargo.toml --workspace |& tee /tmp/f1.txt 16 | target/release/phoenix_cargo --compile-log $PHOENIX_COMPILE_LOG --host-dep $HOST_DEP -- build -v -r |& tee /tmp/f2.txt 17 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | RUN apt update 4 | 5 | RUN DEBIAN_FRONTEND=noninteractive apt install -y \ 6 | --allow-unauthenticated --allow-downgrades --allow-change-held-packages --no-install-recommends \ 7 | sudo \ 8 | build-essential \ 9 | tzdata \ 10 | ca-certificates \ 11 | openssh-server \ 12 | curl \ 13 | wget \ 14 | bison \ 15 | iproute2 \ 16 | iputils-ping dnsutils pciutils \ 17 | iftop \ 18 | unzip \ 19 | cmake \ 20 | git \ 21 | lsb-release \ 22 | numactl 23 | 24 | RUN DEBIAN_FRONTEND=noninteractive apt install -y \ 25 | --allow-unauthenticated --allow-downgrades --allow-change-held-packages --no-install-recommends \ 26 | libclang-dev libnuma-dev librdmacm-dev libibverbs-dev protobuf-compiler 27 | 28 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 29 | RUN echo 'source $HOME/.cargo/env' >> $HOME/.bashrc 30 | ENV PATH="/root/.cargo/bin:${PATH}" 31 | RUN cargo install cargo-make 32 | 33 | RUN git clone https://github.com/phoenix-dataplane/phoenix.git --recursive 34 | 35 | WORKDIR phoenix 36 | -------------------------------------------------------------------------------- /docker/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker build -t phoenixos . 4 | -------------------------------------------------------------------------------- /eval/README.md: -------------------------------------------------------------------------------- 1 | Scripts and other materials related to mRPC paper evaluation goes into 2 | this folder. 3 | -------------------------------------------------------------------------------- /eval/hotel-services/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "FrontendPort": 5000, 3 | "GeoAddress": "rdma0.danyang-06", 4 | "GeoPort": 8083, 5 | "GeoMongoAddress": "mongodb://localhost:27000", 6 | "RateAddress": "rdma0.danyang-06", 7 | "RatePort": 8084, 8 | "RateMongoAddress": "mongodb://localhost:27001", 9 | "RateMemcAddress": "memcache://localhost:17001", 10 | "ProfileAddress": "rdma0.danyang-05", 11 | "ProfilePort": 8085, 12 | "ProfileMongoAddress": "mongodb://localhost:27002", 13 | "ProfileMemcAddress": "memcache://localhost:17002", 14 | "SearchAddress": "rdma0.danyang-04", 15 | "SearchPort": 8086, 16 | "LogPath": "/tmp/mrpc-eval/microservices" 17 | } -------------------------------------------------------------------------------- /eval/hotel-services/config.toml: -------------------------------------------------------------------------------- 1 | workdir = "~/nfs/phoenix" 2 | 3 | [env] 4 | RUST_BACKTRACE = "1" 5 | RUST_LOG_STYLE = "never" 6 | CARGO_TERM_COLOR = "never" 7 | PHOENIX_LOG = "info" 8 | PHOENIX_PREFIX = "/tmp/phoenix" 9 | -------------------------------------------------------------------------------- /eval/hotel-services/docker-compose-geo.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | mongodb-geo: 4 | image: mongo:4.4.6 5 | container_name: 'hotel_reserv_geo_mongo' 6 | command: --port 27000 7 | hostname: geo-db 8 | network_mode: "host" 9 | restart: always 10 | volumes: 11 | - geo:/data/db 12 | 13 | volumes: 14 | geo: 15 | -------------------------------------------------------------------------------- /eval/hotel-services/docker-compose-profile.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | mongodb-profile: 4 | image: mongo:4.4.6 5 | container_name: 'hotel_reserv_profile_mongo' 6 | command: --port 27002 7 | hostname: profile-db 8 | network_mode: "host" 9 | restart: always 10 | volumes: 11 | - profile:/data/db 12 | 13 | memcached-profile: 14 | image: memcached 15 | container_name: 'hotel_reserv_profile_mmc' 16 | command: --port 17002 17 | restart: always 18 | environment: 19 | - MEMCACHED_CACHE_SIZE=128 20 | - MEMCACHED_THREADS=2 21 | network_mode: "host" 22 | logging: 23 | options: 24 | max-size: 50m 25 | 26 | volumes: 27 | profile: 28 | 29 | -------------------------------------------------------------------------------- /eval/hotel-services/docker-compose-rate.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | mongodb-rate: 4 | image: mongo:4.4.6 5 | container_name: 'hotel_reserv_rate_mongo' 6 | command: --port 27001 7 | hostname: rate-db 8 | network_mode: "host" 9 | restart: always 10 | volumes: 11 | - rate:/data/db 12 | 13 | memcached-rate: 14 | image: memcached 15 | container_name: 'hotel_reserv_rate_mmc' 16 | command: --port 17001 17 | restart: always 18 | environment: 19 | - MEMCACHED_CACHE_SIZE=128 20 | - MEMCACHED_THREADS=2 21 | network_mode: "host" 22 | logging: 23 | options: 24 | max-size: 50m 25 | 26 | volumes: 27 | rate: 28 | 29 | -------------------------------------------------------------------------------- /eval/hotel-services/hotel_services.toml: -------------------------------------------------------------------------------- 1 | name = "hotel_microservices" 2 | description = "Run hotel_microservices" 3 | group = "hotel_microservices" 4 | timeout_secs = 600 5 | start_delay = 5 6 | 7 | [[worker]] 8 | host = "danyang-06" 9 | bin = "hotel_reserv_geo" 10 | args = "--config eval/hotel-services/config.json" 11 | term = 2 12 | 13 | [[worker]] 14 | host = "danyang-06" 15 | bin = "hotel_reserv_rate" 16 | args = "--config eval/hotel-services/config.json" 17 | term = 2 18 | 19 | [[worker]] 20 | host = "danyang-05" 21 | bin = "hotel_reserv_profile" 22 | args = "--config eval/hotel-services/config.json" 23 | term = 2 24 | 25 | [[worker]] 26 | host = "danyang-04" 27 | bin = "hotel_reserv_search" 28 | args = "--config eval/hotel-services/config.json" 29 | term = 2 30 | dependencies = [0, 1] 31 | 32 | [[worker]] 33 | host = "danyang-03" 34 | bin = "hotel_reserv_frontend" 35 | args = "--config eval/hotel-services/config.json" 36 | term = 2 37 | dependencies = [0, 1, 2, 3] -------------------------------------------------------------------------------- /eval/hotel-services/launch_phoenix.toml: -------------------------------------------------------------------------------- 1 | name = "launch_phoenix" 2 | description = "Launch phoenix daemon" 3 | group = "launch_phoenix" 4 | timeout_secs = 600 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "phoenix" 9 | args = "-c eval/hotel-services/phoenix.toml" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "phoenix" 14 | args = "-c eval/hotel-services/phoenix.toml" 15 | 16 | [[worker]] 17 | host = "danyang-04" 18 | bin = "phoenix" 19 | args = "-c eval/hotel-services/phoenix.toml" 20 | 21 | [[worker]] 22 | host = "danyang-03" 23 | bin = "phoenix" 24 | args = "-c eval/hotel-services/phoenix.toml" 25 | 26 | -------------------------------------------------------------------------------- /eval/hotel-services/start_containers.sh: -------------------------------------------------------------------------------- 1 | WORKDIR=`dirname $(realpath $0)` 2 | cd $WORKDIR 3 | docker-compose -f docker-compose-profile.yml -H "ssh://root@danyang-05" up -d 4 | docker-compose -f docker-compose-geo.yml -H "ssh://root@danyang-06" up -d 5 | docker-compose -f docker-compose-rate.yml -H "ssh://root@danyang-06" up -d 6 | -------------------------------------------------------------------------------- /eval/hotel-services/start_phoenix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OD=/tmp/mrpc-eval 3 | if [[ $# -ge 1 ]]; then 4 | OD=$1 5 | fi 6 | 7 | WORKDIR=`dirname $(realpath $0)` 8 | cd $WORKDIR 9 | cargo rr --bin launcher -- -o ${OD} --benchmark ./launch_phoenix.toml --configfile ./config.toml --timeout 600 10 | -------------------------------------------------------------------------------- /eval/hotel-services/start_service.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OD=/tmp/mrpc-eval 3 | if [[ $# -ge 1 ]]; then 4 | OD=$1 5 | fi 6 | 7 | WORKDIR=`dirname $(realpath $0)` 8 | cd $WORKDIR 9 | cargo rr --bin launcher -- -o ${OD} --benchmark ./hotel_services.toml --configfile ./config.toml --timeout 600 10 | -------------------------------------------------------------------------------- /eval/hotel-services/stop_containers.sh: -------------------------------------------------------------------------------- 1 | WORKDIR=`dirname $(realpath $0)` 2 | cd $WORKDIR 3 | docker-compose -f docker-compose-profile.yml -H "ssh://root@danyang-05" down 4 | docker-compose -f docker-compose-geo.yml -H "ssh://root@danyang-06" down 5 | docker-compose -f docker-compose-rate.yml -H "ssh://root@danyang-06" down 6 | -------------------------------------------------------------------------------- /eval/micro-bench/bandwidth/README.md: -------------------------------------------------------------------------------- 1 | This folder contains scripts for running large RPC bandwidth mircobenchmark. 2 | **Edit config.toml and phoenix.toml first** 3 | 4 | 1. Start backend 5 | ``` 6 | ./start_phoenix.sh [/tmp/mrpc-eval] 7 | ``` 8 | 9 | 2. Start traffic. This will traverse all the configs and generate 10 | results under `/tmp/mrpc-eval`. 11 | ``` 12 | ./start_traffic_rdma.sh [/tmp/mrpc-eval] 13 | ./start_traffic_tcp.sh [/tmp/mrpc-eval] 14 | ``` 15 | 16 | 3. Collect and parse results. This will read into `/tmp/mrpc-eval` and 17 | parse the text output to csv for plotting figures. 18 | ``` 19 | python3 ./collect.py [/tmp/mrpc-eval] 20 | ``` 21 | -------------------------------------------------------------------------------- /eval/micro-bench/bandwidth/config.toml: -------------------------------------------------------------------------------- 1 | workdir = "~/nfs/Developing/phoenix" 2 | 3 | [env] 4 | RUST_BACKTRACE = "1" 5 | RUST_LOG_STYLE = "never" 6 | CARGO_TERM_COLOR = "never" 7 | PHOENIX_LOG = "info" 8 | PROTOC = "/usr/bin/protoc" 9 | PHOENIX_PREFIX = "/tmp/phoenix" 10 | -------------------------------------------------------------------------------- /eval/micro-bench/bandwidth/launch_phoenix.toml: -------------------------------------------------------------------------------- 1 | name = "launch_phoenix" 2 | description = "Launch phoenix daemon" 3 | group = "launch_phoenix" 4 | timeout_secs = 600 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "phoenix" 9 | args = "-c eval/micro-bench/bandwidth/phoenix.toml" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "phoenix" 14 | args = "-c eval/micro-bench/bandwidth/phoenix.toml" 15 | dependencies = [0] # launch in order, no very necessary 16 | -------------------------------------------------------------------------------- /eval/micro-bench/bandwidth/start_phoenix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OD=/tmp/mrpc-eval 3 | if [[ $# -ge 1 ]]; then 4 | OD=$1 5 | fi 6 | 7 | WORKDIR=`dirname $(realpath $0)` 8 | cd $WORKDIR 9 | cargo rr --bin launcher -- -o ${OD} --benchmark ./launch_phoenix.toml --configfile ./config.toml --timeout 600 10 | -------------------------------------------------------------------------------- /eval/micro-bench/rate/README.md: -------------------------------------------------------------------------------- 1 | This folder contains scripts for benchmarking small RPC rate and 2 | scalability. 3 | **Edit config.toml and phoenix.toml first** 4 | 5 | 1. Start backend 6 | ``` 7 | ./start_phoenix.sh [/tmp/mrpc-eval] 8 | ``` 9 | 10 | 2. Start traffic. This will traverse all the configs and generate 11 | results under `/tmp/mrpc-eval`. 12 | ``` 13 | ./start_traffic_rdma.sh [/tmp/mrpc-eval] 14 | ./start_traffic_tcp.sh [/tmp/mrpc-eval] [danyang-06] 15 | ``` 16 | 17 | 3. Collect and parse results. This will read into `/tmp/mrpc-eval` and 18 | parse the text output to csv for plotting figures. 19 | ``` 20 | python3 ./collect.py [/tmp/mrpc-eval] 21 | ``` 22 | -------------------------------------------------------------------------------- /eval/micro-bench/rate/config.toml: -------------------------------------------------------------------------------- 1 | workdir = "~/nfs/Developing/phoenix" 2 | 3 | [env] 4 | RUST_BACKTRACE = "1" 5 | RUST_LOG_STYLE = "never" 6 | CARGO_TERM_COLOR = "never" 7 | PHOENIX_LOG = "info" 8 | PROTOC = "/usr/bin/protoc" 9 | PHOENIX_PREFIX = "/tmp/phoenix" 10 | -------------------------------------------------------------------------------- /eval/micro-bench/rate/launch_phoenix.toml: -------------------------------------------------------------------------------- 1 | name = "launch_phoenix" 2 | description = "Launch phoenix daemon" 3 | group = "launch_phoenix" 4 | timeout_secs = 600 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "phoenix" 9 | args = "-c eval/micro-bench/rate/phoenix.toml" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "phoenix" 14 | args = "-c eval/micro-bench/rate/phoenix.toml" 15 | dependencies = [0] # launch in order, no very necessary 16 | -------------------------------------------------------------------------------- /eval/micro-bench/rate/start_phoenix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OD=/tmp/mrpc-eval 3 | if [[ $# -ge 1 ]]; then 4 | OD=$1 5 | fi 6 | 7 | WORKDIR=`dirname $(realpath $0)` 8 | cd $WORKDIR 9 | sed -i 's/transport =\(.*\)/transport = "Rdma"/g' phoenix.toml 10 | cargo rr --bin launcher -- -o ${OD} --benchmark ./launch_phoenix.toml --configfile ./config.toml --timeout 600 11 | -------------------------------------------------------------------------------- /eval/policy/chain/phase1/logging_attach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "LoggingEngine" 2 | tx_channels_replacements = [ 3 | [ 4 | "RateLimitEngine", 5 | "LoggingEngine", 6 | 0, 7 | 0, 8 | ], 9 | [ 10 | "LoggingEngine", 11 | "TcpRpcAdapterEngine", 12 | 0, 13 | 0, 14 | ], 15 | ] 16 | rx_channels_replacements = [ 17 | [ 18 | "TcpRpcAdapterEngine", 19 | "LoggingEngine", 20 | 0, 21 | 0, 22 | ], 23 | [ 24 | "LoggingEngine", 25 | "MrpcEngine", 26 | 0, 27 | 0, 28 | ], 29 | ] 30 | group = ["MrpcEngine", "TcpRpcAdapterEngine", "RateLimitEngine"] 31 | op = "attach" 32 | -------------------------------------------------------------------------------- /eval/policy/chain/phase1/ratelimit_attach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "RateLimitEngine" 2 | tx_channels_replacements = [ 3 | [ 4 | "MrpcEngine", 5 | "RateLimitEngine", 6 | 0, 7 | 0, 8 | ], 9 | [ 10 | "RateLimitEngine", 11 | "TcpRpcAdapterEngine", 12 | 0, 13 | 0, 14 | ], 15 | ] 16 | rx_channels_replacements = [] 17 | group = ["MrpcEngine", "TcpRpcAdapterEngine"] 18 | op = "attach" 19 | config_string = ''' 20 | requests_per_sec = 1 21 | bucket_size = 1 22 | ''' 23 | -------------------------------------------------------------------------------- /eval/policy/chain/phase1/receiver_attach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "HelloAclReceiverEngine" 2 | tx_channels_replacements = [ 3 | [ 4 | "MrpcEngine", 5 | "HelloAclReceiverEngine", 6 | 0, 7 | 0, 8 | ], 9 | [ 10 | "HelloAclReceiverEngine", 11 | "TcpRpcAdapterEngine", 12 | 0, 13 | 0, 14 | ], 15 | ] 16 | rx_channels_replacements = [ 17 | [ 18 | "TcpRpcAdapterEngine", 19 | "HelloAclReceiverEngine", 20 | 0, 21 | 0, 22 | ], 23 | [ 24 | "HelloAclReceiverEngine", 25 | "MrpcEngine", 26 | 0, 27 | 0, 28 | ], 29 | ] 30 | group = ["MrpcEngine", "TcpRpcAdapterEngine"] 31 | op = "attach" 32 | config_string = ''' 33 | ''' 34 | -------------------------------------------------------------------------------- /eval/policy/chain/phase2/receiver_detach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "HelloAclReceiverEngine" 2 | tx_channels_replacements = [["MrpcEngine", "TcpRpcAdapterEngine", 0, 0]] 3 | rx_channels_replacements = [["TcpRpcAdapterEngine", "MrpcEngine", 0, 0]] 4 | op = "detach" 5 | -------------------------------------------------------------------------------- /eval/policy/chain/phase2/sender_attach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "HelloAclSenderEngine" 2 | tx_channels_replacements = [ 3 | [ 4 | "LoggingEngine", 5 | "HelloAclSenderEngine", 6 | 0, 7 | 0, 8 | ], 9 | [ 10 | "HelloAclSenderEngine", 11 | "TcpRpcAdapterEngine", 12 | 0, 13 | 0, 14 | ], 15 | ] 16 | rx_channels_replacements = [ 17 | [ 18 | "TcpRpcAdapterEngine", 19 | "HelloAclSenderEngine", 20 | 0, 21 | 0, 22 | ], 23 | [ 24 | "HelloAclSenderEngine", 25 | "LoggingEngine", 26 | 0, 27 | 0, 28 | ], 29 | ] 30 | group = [ 31 | "MrpcEngine", 32 | "TcpRpcAdapterEngine", 33 | "LoggingEngine", 34 | "RateLimitEngine", 35 | ] 36 | op = "attach" 37 | config_string = ''' 38 | ''' 39 | -------------------------------------------------------------------------------- /eval/policy/chain/phase3/logging_detach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "LoggingEngine" 2 | tx_channels_replacements = [["RateLimitEngine", "HelloAclSenderEngine", 0, 0]] 3 | rx_channels_replacements = [["HelloAclSenderEngine", "MrpcEngine", 0, 0]] 4 | op = "detach" 5 | -------------------------------------------------------------------------------- /eval/policy/chain/phase3/ratelimit_detach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "RateLimitEngine" 2 | tx_channels_replacements = [["MrpcEngine", "TcpRpcAdapterEngine", 0, 0]] 3 | rx_channels_replacements = [] 4 | op = "detach" 5 | -------------------------------------------------------------------------------- /eval/policy/chain/phase3/sender_detach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "HelloAclSenderEngine" 2 | tx_channels_replacements = [["RateLimitEngine", "TcpRpcAdapterEngine", 0, 0]] 3 | rx_channels_replacements = [["TcpRpcAdapterEngine", "MrpcEngine", 0, 0]] 4 | op = "detach" 5 | -------------------------------------------------------------------------------- /eval/policy/hello-acl-receiver/attach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "HelloAclReceiverEngine" 2 | tx_channels_replacements = [ 3 | [ 4 | "MrpcEngine", 5 | "HelloAclReceiverEngine", 6 | 0, 7 | 0, 8 | ], 9 | [ 10 | "HelloAclReceiverEngine", 11 | "TcpRpcAdapterEngine", 12 | 0, 13 | 0, 14 | ], 15 | ] 16 | rx_channels_replacements = [ 17 | [ 18 | "TcpRpcAdapterEngine", 19 | "HelloAclReceiverEngine", 20 | 0, 21 | 0, 22 | ], 23 | [ 24 | "HelloAclReceiverEngine", 25 | "MrpcEngine", 26 | 0, 27 | 0, 28 | ], 29 | ] 30 | group = ["MrpcEngine", "TcpRpcAdapterEngine"] 31 | op = "attach" 32 | config_string = ''' 33 | ''' 34 | -------------------------------------------------------------------------------- /eval/policy/hello-acl-receiver/detach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "HelloAclReceiverEngine" 2 | tx_channels_replacements = [["MrpcEngine", "TcpRpcAdapterEngine", 0, 0]] 3 | rx_channels_replacements = [] 4 | op = "detach" 5 | -------------------------------------------------------------------------------- /eval/policy/hotel-acl/README.md: -------------------------------------------------------------------------------- 1 | This folder contains scripts for content-based-ACL policy. 2 | **Edit config.toml and phoenix.toml first** 3 | 4 | 1. Start receiver backend on `danyang-06`. Start sender backend on 5 | `danyang-05`. 6 | ``` 7 | cjr@danyang-05 $ ./start_phoenix.sh [/tmp/mrpc-eval] 8 | ``` 9 | 10 | 2. Start traffic 11 | ``` 12 | ./start_traffic.sh [/tmp/mrpc-eval] 13 | ``` 14 | 15 | 3. Collect and parse results. This will read into `/tmp/mrpc-eval` and 16 | parse the text output to csv for plotting figures. 17 | ``` 18 | python3 ./collect.py [/tmp/mrpc-eval] 19 | ``` 20 | -------------------------------------------------------------------------------- /eval/policy/hotel-acl/attach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "HotelAclEngine" 2 | tx_channels_replacements = [ 3 | ["MrpcEngine", "HotelAclEngine", 0, 0], 4 | ["HotelAclEngine", "RpcAdapterEngine", 0, 0], 5 | ] 6 | rx_channels_replacements = [ 7 | ["RpcAdapterEngine", "HotelAclEngine", 0, 0], 8 | ["HotelAclEngine", "MrpcEngine", 0, 0], 9 | ] 10 | group = ["MrpcEngine", "RpcAdapterEngine"] 11 | op = "attach" 12 | config_string = ''' 13 | ''' 14 | -------------------------------------------------------------------------------- /eval/policy/hotel-acl/attach_tcp.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "HotelAclEngine" 2 | tx_channels_replacements = [ 3 | ["MrpcEngine", "HotelAclEngine", 0, 0], 4 | ["HotelAclEngine", "TcpRpcAdapterEngine", 0, 0], 5 | ] 6 | rx_channels_replacements = [ 7 | ["TcpRpcAdapterEngine", "HotelAclEngine", 0, 0], 8 | ["HotelAclEngine", "MrpcEngine", 0, 0], 9 | ] 10 | group = ["MrpcEngine", "TcpRpcAdapterEngine"] 11 | op = "attach" 12 | config_string = ''' 13 | ''' 14 | -------------------------------------------------------------------------------- /eval/policy/hotel-acl/collect.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from typing import List 3 | import glob 4 | import sys 5 | 6 | OD = "/tmp/mrpc-eval" 7 | if len(sys.argv) >= 2: 8 | OD = sys.argv[1] 9 | 10 | 11 | def convert_msg_size(s: str) -> int: 12 | if s.endswith('gb'): 13 | return int(s[:-2]) * 1024 * 1024 * 1024 14 | if s.endswith('mb'): 15 | return int(s[:-2]) * 1024 * 1024 16 | if s.endswith('kb'): 17 | return int(s[:-2]) * 1024 18 | if s.endswith('b'): 19 | return int(s[:-1]) 20 | 21 | raise ValueError(f"unknown input: {s}") 22 | 23 | 24 | def get_rate(path: str) -> List[float]: 25 | rates = [] 26 | with open(path, 'r') as fin: 27 | for line in fin: 28 | words = line.strip().split(' ') 29 | if words[1] == 'rps,': 30 | rate = float(words[-4]) 31 | rates.append(rate) 32 | return rates[1:] 33 | 34 | 35 | def load_result(sol_before, sol_after, f: str): 36 | # print(f) 37 | rates = get_rate(f) 38 | before = rates[5:25] 39 | after = rates[-25:-5] 40 | for r in before: 41 | print(f'{round(r/1000,2)},{sol_before},w/o ACL') 42 | for r in after: 43 | print(f'{round(r/1000,2)},{sol_after},w/ ACL') 44 | 45 | 46 | for f in glob.glob(OD+"/benchmark/hotel_reservation/hotel_reservation_client_danyang-05.stdout"): 47 | load_result('mRPC', 'mRPC', f) 48 | -------------------------------------------------------------------------------- /eval/policy/hotel-acl/config.toml: -------------------------------------------------------------------------------- 1 | workdir = "~/nfs/Developing/phoenix" 2 | 3 | [env] 4 | RUST_BACKTRACE = "1" 5 | RUST_LOG_STYLE = "never" 6 | CARGO_TERM_COLOR = "never" 7 | PHOENIX_LOG = "info" 8 | PROTOC = "/usr/bin/protoc" 9 | PHOENIX_PREFIX = "/tmp/phoenix" 10 | -------------------------------------------------------------------------------- /eval/policy/hotel-acl/detach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "HotelAclEngine" 2 | tx_channels_replacements = [["MrpcEngine", "RpcAdapterEngine", 0, 0]] 3 | rx_channels_replacements = [["RpcAdapterEngine", "MrpcEngine", 0, 0]] 4 | op = "detach" 5 | -------------------------------------------------------------------------------- /eval/policy/hotel-acl/detach_tcp.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "HotelAclEngine" 2 | tx_channels_replacements = [ 3 | ["MrpcEngine", "TcpRpcAdapterEngine", 0, 0], 4 | ] 5 | rx_channels_replacements = [] 6 | op = "detach" 7 | -------------------------------------------------------------------------------- /eval/policy/hotel-acl/hotel_reservation.toml: -------------------------------------------------------------------------------- 1 | name = "benchmark/hotel_reservation" 2 | description = "Run hotel_reservation rate test" 3 | group = "hotel_reservation" 4 | timeout_secs = 70 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "hotel_reservation_server" 9 | args = "--transport tcp" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "hotel_reservation_client" 14 | args = "--transport tcp -c rdma0.danyang-06 --concurrency 128 -D 65 -i 1" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /eval/policy/hotel-acl/launch_phoenix.toml: -------------------------------------------------------------------------------- 1 | name = "launch_phoenix" 2 | description = "Launch phoenix daemon" 3 | group = "launch_phoenix" 4 | timeout_secs = 600 5 | 6 | [[worker]] 7 | host = "danyang-05" 8 | bin = "phoenix" 9 | args = "-c eval/policy/hotel-acl/phoenix.toml --no-ansi" 10 | 11 | [[worker]] 12 | host = "danyang-06" 13 | bin = "phoenix" 14 | args = "-c eval/policy/hotel-acl/phoenix.toml --no-ansi" 15 | dependencies = [0] # launch in order, not very necessary 16 | -------------------------------------------------------------------------------- /eval/policy/hotel-acl/start_phoenix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OD=/tmp/mrpc-eval 3 | if [[ $# -ge 1 ]]; then 4 | OD=$1 5 | fi 6 | 7 | WORKDIR=`dirname $(realpath $0)` 8 | cd $WORKDIR 9 | cargo rr --bin launcher -- -o ${OD} --benchmark ./launch_phoenix.toml --configfile ./config.toml --timeout 600 10 | -------------------------------------------------------------------------------- /eval/policy/hotel-acl/start_traffic.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM SIGHUP EXIT 4 | 5 | OD=/tmp/mrpc-eval 6 | if [[ $# -ge 1 ]]; then 7 | OD=$1 8 | fi 9 | 10 | WORKDIR=$(dirname $(realpath $0)) 11 | cd $WORKDIR 12 | 13 | # concurrency = 128 14 | cargo rr --bin launcher -- --output-dir ${OD} --timeout=120 --benchmark ./hotel_reservation.toml --configfile ./config.toml & 15 | 16 | sleep 30 17 | 18 | LIST_OUTPUT="${OD}"/policy/list.json 19 | cargo rr --bin list -- --dump "${LIST_OUTPUT}" # Need to specifiy PHOENIX_PREFIX 20 | cat "${LIST_OUTPUT}" 21 | ARG_PID=$(cat "${LIST_OUTPUT}" | jq '.[] | select(.service == "Mrpc") | .pid') 22 | ARG_SID=$(cat "${LIST_OUTPUT}" | jq '.[] | select(.service == "Mrpc") | .sid') 23 | echo $ARG_SID 24 | 25 | sleep 1 26 | 27 | cargo run --bin addonctl -- --config ./attach_tcp.toml --pid ${ARG_PID} --sid ${ARG_SID} # Need to specifiy PHOENIX_PREFIX 28 | 29 | wait 30 | -------------------------------------------------------------------------------- /eval/policy/logging/attach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "LoggingEngine" 2 | tx_channels_replacements = [ 3 | ["MrpcEngine", "LoggingEngine", 0, 0], 4 | ["LoggingEngine", "TcpRpcAdapterEngine", 0, 0], 5 | ] 6 | rx_channels_replacements = [ 7 | ["TcpRpcAdapterEngine", "LoggingEngine", 0, 0], 8 | ["LoggingEngine", "MrpcEngine", 0, 0], 9 | ] 10 | group = ["MrpcEngine", "TcpRpcAdapterEngine"] 11 | op = "attach" 12 | -------------------------------------------------------------------------------- /eval/policy/logging/detach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "LoggingEngine" 2 | tx_channels_replacements = [ 3 | ["MrpcEngine", "RpcAdapterEngine", 0, 0], 4 | ] 5 | rx_channels_replacements = [] 6 | op = "detach" 7 | -------------------------------------------------------------------------------- /eval/policy/null/README.md: -------------------------------------------------------------------------------- 1 | This folder contains scripts for null policy. 2 | **Edit config.toml and phoenix.toml first** 3 | 4 | 1. Start receiver backend on `danyang-06`. Start sender backend on 5 | `danyang-05`. 6 | ``` 7 | cjr@danyang-05 $ ./start_phoenix.sh [/tmp/mrpc-eval] 8 | ``` 9 | 10 | 2. Start the rpc_bench_server and rpc_bench_client 11 | ``` 12 | cjr@danyang-05 $ ./start_traffic_tcp.sh [/tmp/mrpc-eval] 13 | cjr@danyang-05 $ ./start_traffic_rdma.sh [/tmp/mrpc-eval] 14 | ``` 15 | 16 | 3. Attach policy at the client and the server 17 | ``` 18 | cjr@danyang-05 $ python3 attach_policy.py [/tmp/mrpc-eval] 19 | cjr@danyang-06 $ python3 attach_policy.py [/tmp/mrpc-eval] 20 | ``` 21 | 22 | 3. Wait for finshing rpc_bench. 23 | 24 | -------------------------------------------------------------------------------- /eval/policy/null/attach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "NullEngine" 2 | tx_channels_replacements = [ 3 | ["MrpcEngine", "NullEngine", 0, 0], 4 | ["NullEngine", "TcpRpcAdapterEngine", 0, 0], 5 | ] 6 | rx_channels_replacements = [] 7 | group = ["MrpcEngine", "TcpRpcAdapterEngine"] 8 | op = "attach" 9 | -------------------------------------------------------------------------------- /eval/policy/null/attach_policy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OD=/tmp/mrpc-eval 3 | if [[ $# -ge 1 ]]; then 4 | OD=$1 5 | fi 6 | 7 | python3 attach_policy.py ${OD} 8 | 9 | sleep 1 10 | 11 | PWD=$(pwd) 12 | ssh danyang-06 "cd ${PWD}; python3 attach_policy.py ${OD}" 13 | -------------------------------------------------------------------------------- /eval/policy/null/config.toml: -------------------------------------------------------------------------------- 1 | workdir = "~/nfs/Developing/phoenix" 2 | 3 | [env] 4 | RUST_BACKTRACE = "1" 5 | RUST_LOG_STYLE = "never" 6 | CARGO_TERM_COLOR = "never" 7 | PHOENIX_LOG = "info" 8 | PROTOC = "/usr/bin/protoc" 9 | PHOENIX_PREFIX = "/tmp/phoenix" 10 | -------------------------------------------------------------------------------- /eval/policy/null/detach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "NullEngine" 2 | tx_channels_replacements = [ 3 | ["MrpcEngine", "TcpRpcAdapterEngine", 0, 0], 4 | ] 5 | rx_channels_replacements = [] 6 | op = "detach" 7 | -------------------------------------------------------------------------------- /eval/policy/null/launch_phoenix.toml: -------------------------------------------------------------------------------- 1 | name = "launch_phoenix" 2 | description = "Launch phoenix daemon" 3 | group = "launch_phoenix" 4 | timeout_secs = 600 5 | 6 | [[worker]] 7 | host = "danyang-05" 8 | bin = "phoenix" 9 | args = "-c eval/policy/null/phoenix.toml --no-ansi" 10 | 11 | [[worker]] 12 | host = "danyang-06" 13 | bin = "phoenix" 14 | args = "-c eval/policy/null/phoenix.toml --no-ansi" 15 | dependencies = [0] # launch in order, no very necessary 16 | -------------------------------------------------------------------------------- /eval/policy/null/rpc_bench_latency_64b.toml: -------------------------------------------------------------------------------- 1 | name = "policy/null/rpc_bench_latency_64b" 2 | description = "Run rpc_bench benchmark" 3 | group = "null" 4 | timeout_secs = 40 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 1 --req-size 64 -t 65536" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /eval/policy/null/start_phoenix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OD=/tmp/mrpc-eval 3 | if [[ $# -ge 1 ]]; then 4 | OD=$1 5 | fi 6 | 7 | WORKDIR=`dirname $(realpath $0)` 8 | cd $WORKDIR 9 | sed -i 's/transport =\(.*\)/transport = "Rdma"/g' phoenix.toml 10 | cargo rr --bin launcher -- -o ${OD} --benchmark ./launch_phoenix.toml --configfile ./config.toml --timeout 600 11 | -------------------------------------------------------------------------------- /eval/policy/null/start_traffic_rdma.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OD=/tmp/mrpc-eval 3 | if [[ $# -ge 1 ]]; then 4 | OD=$1 5 | fi 6 | 7 | WORKDIR=$(dirname $(realpath $0)) 8 | cd $WORKDIR 9 | 10 | # concurrency = 1 11 | sed -i 's/--transport \(rdma\|tcp\)//g' ./rpc_bench_latency_64b.toml 12 | sed -i 's/--transport /--transport rdma /g' ./rpc_bench_latency_64b.toml 13 | sed -i 's/TcpRpcAdapterEngine/RpcAdapterEngine/g' attach.toml 14 | cargo rr --bin launcher -- --output-dir ${OD} --benchmark ./rpc_bench_latency_64b.toml --configfile ./config.toml 15 | -------------------------------------------------------------------------------- /eval/policy/null/start_traffic_tcp.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OD=/tmp/mrpc-eval 3 | if [[ $# -ge 1 ]]; then 4 | OD=$1 5 | fi 6 | 7 | WORKDIR=$(dirname $(realpath $0)) 8 | cd $WORKDIR 9 | 10 | # concurrency = 1 11 | sed -i 's/--transport \(rdma\|tcp\)//g' ./rpc_bench_latency_64b.toml 12 | sed -i 's/--transport /--transport rdma /g' ./rpc_bench_latency_64b.toml 13 | sed -i 's/\"RpcAdapterEngine\"/\"TcpRpcAdapterEngine\"/g' attach.toml 14 | cargo rr --bin launcher -- --output-dir ${OD} --benchmark ./rpc_bench_latency_64b.toml --configfile ./config.toml 15 | -------------------------------------------------------------------------------- /eval/policy/qos/README.md: -------------------------------------------------------------------------------- 1 | This folder contains scripts for QoS policy. 2 | **Edit config.toml, phoenix_client.toml phoenix_server.toml first** 3 | 4 | 1. Start receiver backend on `danyang-06`. Start sender backend on 5 | `danyang-05`. 6 | ``` 7 | cjr@danyang-05 $ ./start_phoenix.sh [/tmp/mrpc-eval] 8 | ``` 9 | 10 | 2. Run QoS 11 | ``` 12 | python3 run_qos.py [/tmp/mrpc-eval] 13 | ``` 14 | 15 | NOTE: In this benchmark, we need to start two client-server pairs. 16 | Due to the implementation of process killing of benchmark launcher, an error will occur at the end, 17 | as one of the benchmark launcher will kill the client/server processes of both the benchmarks. 18 | Safe to ignore the errors. -------------------------------------------------------------------------------- /eval/policy/qos/attach_high_priority.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "QosEngine" 2 | tx_channels_replacements = [ 3 | ["MrpcEngine", "QosEngine", 0, 0], 4 | ["QosEngine", "RpcAdapterEngine", 0, 0], 5 | ] 6 | rx_channels_replacements = [] 7 | group = ["MrpcEngine", "RpcAdapterEngine"] 8 | op = "attach" 9 | config_string = ''' 10 | latency_budget_microsecs = 0 11 | ''' 12 | -------------------------------------------------------------------------------- /eval/policy/qos/attach_low_priority.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "QosEngine" 2 | tx_channels_replacements = [ 3 | ["MrpcEngine", "QosEngine", 0, 0], 4 | ["QosEngine", "RpcAdapterEngine", 0, 0], 5 | ] 6 | rx_channels_replacements = [] 7 | group = ["MrpcEngine", "RpcAdapterEngine"] 8 | op = "attach" 9 | config_string = ''' 10 | latency_budget_microsecs = 3 11 | ''' 12 | -------------------------------------------------------------------------------- /eval/policy/qos/brusty_bandwidth.toml: -------------------------------------------------------------------------------- 1 | name = "policy/qos/bandwidth_app" 2 | description = "Run rpc_bench benchmark" 3 | group = "qos_bandwidth" 4 | timeout_secs = 55 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "--port 5002 -l info" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_brusty_client" 14 | args = "-c rdma0.danyang-06 --concurrency 64 --req-size 32768 --duration 20 --send-interval 500 -i 5 --port 5002 --startup-delay 20 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /eval/policy/qos/brusty_latency.toml: -------------------------------------------------------------------------------- 1 | name = "policy/qos/latency_app" 2 | description = "Run rpc_bench benchmark" 3 | group = "qos_latency" 4 | timeout_secs = 55 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "--port 5001 -l info" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_brusty_client" 14 | args = "-c rdma0.danyang-06 --concurrency 1 --req-size 64 --duration 20 --send-interval 100 -i 5 --port 5001 --startup-delay 20 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /eval/policy/qos/config.toml: -------------------------------------------------------------------------------- 1 | workdir = "~/nfs/phoenix" 2 | 3 | [env] 4 | RUST_BACKTRACE = "1" 5 | RUST_LOG_STYLE = "never" 6 | CARGO_TERM_COLOR = "never" 7 | PHOENIX_LOG = "info" 8 | PHOENIX_PREFIX = "/tmp/phoenix" 9 | -------------------------------------------------------------------------------- /eval/policy/qos/launch_phoenix.toml: -------------------------------------------------------------------------------- 1 | name = "launch_phoenix" 2 | description = "Launch phoenix daemon" 3 | group = "launch_phoenix" 4 | timeout_secs = 600 5 | 6 | [[worker]] 7 | host = "danyang-05" 8 | bin = "phoenix" 9 | args = "-c eval/policy/qos/phoenix_client.toml" 10 | 11 | [[worker]] 12 | host = "danyang-06" 13 | bin = "phoenix" 14 | args = "-c eval/policy/qos/phoenix_server.toml" 15 | dependencies = [0] # launch in order, no very necessary 16 | -------------------------------------------------------------------------------- /eval/policy/qos/start_phoenix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OD=/tmp/mrpc-eval 3 | if [[ $# -ge 1 ]]; then 4 | OD=$1 5 | fi 6 | 7 | WORKDIR=`dirname $(realpath $0)` 8 | cd $WORKDIR 9 | cargo rr --bin launcher -- -o ${OD} --benchmark ./launch_phoenix.toml --configfile ./config.toml --timeout 600 10 | -------------------------------------------------------------------------------- /eval/policy/ratelimit/README.md: -------------------------------------------------------------------------------- 1 | This folder contains scripts for rate limit policy. 2 | **Edit config.toml and phoenix.toml first** 3 | 4 | 1. Start receiver backend on `danyang-06`. Start sender backend on 5 | `danyang-05`. 6 | ``` 7 | cjr@danyang-05 $ ./start_phoenix.sh [/tmp/mrpc-eval] 8 | ``` 9 | 10 | 2. Run policy 11 | ``` 12 | python3 run_policy.py [/tmp/mrpc-eval] 13 | ``` 14 | 15 | 3. Collect and parse results. This will read into `/tmp/mrpc-eval` and 16 | parse the text output to csv for plotting figures. 17 | ``` 18 | python3 ./collect.py [/tmp/mrpc-eval] 19 | ``` 20 | -------------------------------------------------------------------------------- /eval/policy/ratelimit/attach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "RateLimitEngine" 2 | tx_channels_replacements = [ 3 | ["MrpcEngine", "RateLimitEngine", 0, 0], 4 | ["RateLimitEngine", "TcpRpcAdapterEngine", 0, 0], 5 | ] 6 | rx_channels_replacements = [] 7 | group = ["MrpcEngine", "TcpRpcAdapterEngine"] 8 | op = "attach" 9 | config_string = ''' 10 | requests_per_sec = 10000000 11 | bucket_size = 10000000 12 | ''' 13 | -------------------------------------------------------------------------------- /eval/policy/ratelimit/collect.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from typing import List 3 | import glob 4 | import sys 5 | 6 | OD = "/tmp/mrpc-eval" 7 | if len(sys.argv) >= 2: 8 | OD = sys.argv[1] 9 | 10 | 11 | def get_rate(path: str) -> List[float]: 12 | rates = [] 13 | with open(path, 'r') as fin: 14 | for line in fin: 15 | words = line.strip().split(' ') 16 | if words[-3] == 'rps,': 17 | rate = float(words[-4]) 18 | rates.append(rate) 19 | return rates[1:] 20 | 21 | 22 | def load_result(sol_before, sol_after, f: str): 23 | rates = get_rate(f) 24 | before = rates[5:25] 25 | after = rates[-25:-5] 26 | for r in before: 27 | print(f'{round(r/1000,2)},{sol_before},w/o Limit') 28 | for r in after: 29 | print(f'{round(r/1000,2)},{sol_after},w/ Limit') 30 | 31 | 32 | for f in glob.glob(OD+"/policy/ratelimit/rpc_bench_tput_32b/rpc_bench_client_danyang-05.stdout"): 33 | load_result('mRPC', 'mRPC', f) 34 | -------------------------------------------------------------------------------- /eval/policy/ratelimit/config.toml: -------------------------------------------------------------------------------- 1 | workdir = "~/nfs/phoenix" 2 | 3 | [env] 4 | RUST_BACKTRACE = "1" 5 | RUST_LOG_STYLE = "never" 6 | CARGO_TERM_COLOR = "never" 7 | PHOENIX_LOG = "info" 8 | PROTOC = "/usr/bin/protoc" 9 | PHOENIX_PREFIX = "/tmp/phoenix" 10 | -------------------------------------------------------------------------------- /eval/policy/ratelimit/detach.toml: -------------------------------------------------------------------------------- 1 | addon_engine = "RateLimitEngine" 2 | tx_channels_replacements = [ 3 | ["MrpcEngine", "TcpRpcAdapterEngine", 0, 0], 4 | ] 5 | rx_channels_replacements = [] 6 | op = "detach" 7 | -------------------------------------------------------------------------------- /eval/policy/ratelimit/launch_phoenix.toml: -------------------------------------------------------------------------------- 1 | name = "launch_phoenix" 2 | description = "Launch phoenix daemon" 3 | group = "launch_phoenix" 4 | timeout_secs = 600 5 | 6 | [[worker]] 7 | host = "danyang-05" 8 | bin = "phoenix" 9 | args = "-c eval/policy/ratelimit/phoenix.toml --no-ansi" 10 | 11 | [[worker]] 12 | host = "danyang-06" 13 | bin = "phoenix" 14 | args = "-c eval/policy/ratelimit/phoenix.toml --no-ansi" 15 | dependencies = [0] # launch in order, no very necessary 16 | -------------------------------------------------------------------------------- /eval/policy/ratelimit/rpc_bench_tput_32b.toml: -------------------------------------------------------------------------------- 1 | name = "policy/ratelimit/rpc_bench_tput_32b" 2 | description = "Run rpc_bench benchmark" 3 | group = "ratelimit" 4 | timeout_secs = 70 5 | 6 | [[worker]] 7 | host = "danyang-06" 8 | bin = "rpc_bench_server" 9 | args = "--port 5002 -l info" 10 | 11 | [[worker]] 12 | host = "danyang-05" 13 | bin = "rpc_bench_client" 14 | args = "-c rdma0.danyang-06 --concurrency 128 --req-size 32 --duration 65 -i 1 --port 5002 -l info" 15 | dependencies = [0] 16 | -------------------------------------------------------------------------------- /eval/policy/ratelimit/start_phoenix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OD=/tmp/mrpc-eval 3 | if [[ $# -ge 1 ]]; then 4 | OD=$1 5 | fi 6 | 7 | WORKDIR=`dirname $(realpath $0)` 8 | cd $WORKDIR 9 | cargo rr --bin launcher -- -o ${OD} --benchmark ./launch_phoenix.toml --configfile ./config.toml --timeout 600 10 | -------------------------------------------------------------------------------- /eval/upgrade/rpc_adapter.toml: -------------------------------------------------------------------------------- 1 | [[modules]] 2 | name = "RpcAdapter" 3 | lib_path = "/tmp/phoenix/plugins/libphoenix_rpc_adapter_plugin.so" 4 | -------------------------------------------------------------------------------- /examples/alltoall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "alltoall" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-syscalls.workspace = true 10 | clap = { workspace = true, features = ["derive"] } 11 | anyhow.workspace = true 12 | arg_enum_proc_macro = "0.3.2" 13 | -------------------------------------------------------------------------------- /examples/bench/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bench" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-syscalls.workspace = true 10 | 11 | clap = { workspace = true, features = ["derive"] } 12 | scheduler.workspace = true 13 | libnuma.workspace = true 14 | 15 | 16 | [[bin]] 17 | name = "bench_lat" 18 | path = "src/bench_lat.rs" 19 | 20 | [[bin]] 21 | name = "bench_bw" 22 | path = "src/bench_bw.rs" 23 | -------------------------------------------------------------------------------- /examples/bench/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(allocator_api)] 2 | 3 | #[macro_use] 4 | pub mod util; 5 | 6 | pub mod read_lat; 7 | pub mod send_lat; 8 | pub mod write_lat; 9 | 10 | pub mod read_bw; 11 | pub mod send_bw; 12 | pub mod write_bw; 13 | -------------------------------------------------------------------------------- /examples/hello/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-syscalls.workspace = true 10 | 11 | 12 | [[bin]] 13 | name = "sender" 14 | path = "src/sender.rs" 15 | 16 | [[bin]] 17 | name = "receiver" 18 | path = "src/receiver.rs" 19 | -------------------------------------------------------------------------------- /examples/send_bw/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "send_bw" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-syscalls.workspace = true 10 | 11 | clap = { workspace = true, features = ["derive"] } 12 | -------------------------------------------------------------------------------- /examples/send_lat/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "send_lat" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-syscalls.workspace = true 10 | 11 | clap = { workspace = true, features = ["derive"] } 12 | -------------------------------------------------------------------------------- /experimental/README.md: -------------------------------------------------------------------------------- 1 | # Phoenix Experimental Features 2 | - mRPC 3 | -------------------------------------------------------------------------------- /experimental/mrpc/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /experimental/mrpc/README.md: -------------------------------------------------------------------------------- 1 | # mRPC: Remote Procedure Call as a Managed System Service 2 | 3 | mRPC, a managed RPC service, is built on top of Phoenix. mRPC realizes a novel RPC architecture that decouples (un)marshalling from RPC libraries to a centralized system service. 4 | 5 | Compared with traditional library + sidecar solutions such as gRPC + Envoy, mRPC applies network policies and observability features with both security and low performance overhead, i.e., with minimal data movement and no redundant (un)marshalling. The mechanism supports live upgrade of RPC bindings, policies, transports, and marshalling without disrupting running applications. 6 | 7 | ## Dynamically Load mRPC Plugins 8 | You can dynamically load mRPC plugins to phoenixos. First, change 9 | directory to the phoenix project's root workspace. We provide a set of phoenix-cli 10 | utilities as admin tools under `src/phoenixctl`. 11 | ```bash 12 | cargo run --release --bin upgrade -- --config experimental/mrpc/load-mrpc-plugins.toml 13 | ``` 14 | 15 | `load-mrpc-plugins.toml` specifies the modules and addons to load. You 16 | can change the configuration of them. After MrpcEngine, RpcAdapter, and 17 | TcpRpcAdapter are loaded, you can run mRPC example applications. 18 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/hotel_microservices/build.rs: -------------------------------------------------------------------------------- 1 | const PROTO_DIR: &str = "../proto/hotel_microservices"; 2 | 3 | const PROTOS: &[&str] = &[ 4 | "../proto/hotel_microservices/geo.proto", 5 | "../proto/hotel_microservices/rate.proto", 6 | "../proto/hotel_microservices/search.proto", 7 | "../proto/hotel_microservices/profile.proto", 8 | ]; 9 | 10 | fn main() -> Result<(), Box> { 11 | for proto in PROTOS.iter() { 12 | println!("cargo:rerun-if-changed={proto}"); 13 | } 14 | let builder = mrpc_build::configure(); 15 | builder.compile(PROTOS, &[PROTO_DIR])?; 16 | Ok(()) 17 | } 18 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/hotel_microservices/src/logging.rs: -------------------------------------------------------------------------------- 1 | pub fn init_env_log(filter_env: &str, default_level: &str) { 2 | use chrono::Utc; 3 | use std::io::Write; 4 | 5 | let env = env_logger::Env::new().filter_or(filter_env, default_level); 6 | env_logger::Builder::from_env(env) 7 | .format(|buf, record| { 8 | let level_style = buf.default_level_style(record.level()); 9 | writeln!( 10 | buf, 11 | "[{} {} {}:{}] {}", 12 | Utc::now().format("%Y-%m-%d %H:%M:%S%.6f"), 13 | level_style.value(record.level()), 14 | record.file().unwrap_or(""), 15 | record.line().unwrap_or(0), 16 | &record.args() 17 | ) 18 | }) 19 | .init(); 20 | 21 | log::info!("env_logger initialized"); 22 | } 23 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/hotel_reservation/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hotel_reservation" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [build-dependencies] 9 | mrpc-build.workspace = true 10 | 11 | [dependencies] 12 | mrpc.workspace = true 13 | prost = { workspace = true, features = ["mrpc-frontend"] } 14 | 15 | structopt.workspace = true 16 | futures.workspace = true 17 | smol.workspace = true 18 | minstant.workspace = true 19 | hdrhistogram.workspace = true 20 | fastrand.workspace = true 21 | 22 | 23 | [[bin]] 24 | name = "hotel_reservation_client" 25 | path = "src/client.rs" 26 | 27 | [[bin]] 28 | name = "hotel_reservation_server" 29 | path = "src/server.rs" 30 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/hotel_reservation/README.md: -------------------------------------------------------------------------------- 1 | Synthesis workload for[hotel reservation](https://github.com/delimitrou/DeathStarBench/blob/master/hotelReservation/services/reservation/proto/reservation.proto) 2 | in DeathStarBench. 3 | 4 | This example is used to evaulate the efficiency for content-based ACL. 5 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/hotel_reservation/build.rs: -------------------------------------------------------------------------------- 1 | const PROTO: &str = "../proto/reservation/reservation.proto"; 2 | fn main() -> Result<(), Box> { 3 | println!("cargo:rerun-if-changed={PROTO}"); 4 | mrpc_build::compile_protos(PROTO)?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/load_balancer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lb" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [build-dependencies] 9 | mrpc-build.workspace = true 10 | 11 | [dependencies] 12 | mrpc.workspace = true 13 | prost = { workspace = true, features = ["mrpc-frontend"] } 14 | 15 | structopt.workspace = true 16 | smol.workspace = true 17 | 18 | 19 | [[bin]] 20 | name = "server" 21 | path = "src/server.rs" 22 | 23 | [[bin]] 24 | name = "client" 25 | path = "src/client.rs" 26 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/load_balancer/README.md: -------------------------------------------------------------------------------- 1 | ## Build the application 2 | 3 | ```bash 4 | # In phoenix/experimental/mrpc 5 | cargo build --release --workspace -p rpc_hello_frontend 6 | ``` 7 | 8 | ## Run the application with client 9 | 10 | ```bash 11 | cargo rr -p rpc_echo --bin rpc_echo_server 12 | # In a seperate terminal 13 | cargo rr -p rpc_echo --bin rpc_echo_client 14 | ``` 15 | 16 | ## Run the application with frontend 17 | 18 | ```bash 19 | cargo rr -p rpc_echo --bin rpc_echo_server 20 | # In a seperate terminal 21 | cargo rr -p rpc_echo --bin rpc_echo_frontend 22 | # In a seperate terminal 23 | curl http://127.0.0.1:7878/hello 24 | ``` -------------------------------------------------------------------------------- /experimental/mrpc/examples/load_balancer/build.rs: -------------------------------------------------------------------------------- 1 | const PROTO: &str = "../proto/rpc_hello/rpc_hello.proto"; 2 | fn main() -> Result<(), Box> { 3 | println!("cargo:rerun-if-changed={PROTO}"); 4 | mrpc_build::compile_protos(PROTO)?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/masstree_analytics/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "masstree_analytics" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [build-dependencies] 9 | cmake.workspace = true 10 | mrpc-build.workspace = true 11 | 12 | [dependencies] 13 | mrpc.workspace = true 14 | prost = { workspace = true, features = ["mrpc-frontend"] } 15 | 16 | chrono.workspace = true 17 | env_logger.workspace = true 18 | fasthash.workspace = true 19 | link-cplusplus.workspace = true 20 | log.workspace = true 21 | nix = { workspace = true, features = ["signal"], default-features = false } 22 | structopt = { workspace = true, features = ["color", "suggestions", "doc"] } 23 | smol.workspace = true 24 | minstant.workspace = true 25 | futures.workspace = true 26 | fastrand.workspace = true 27 | arc-swap.workspace = true 28 | crossbeam-utils.workspace = true 29 | 30 | [[bin]] 31 | name = "masstree_analytics_client" 32 | path = "src/client.rs" 33 | 34 | [[bin]] 35 | name = "masstree_analytics_server" 36 | path = "src/server.rs" 37 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/masstree_analytics/README.md: -------------------------------------------------------------------------------- 1 | # masstree analytics 2 | 3 | `bash 4 | git submodule update --recursive --init 5 | ` 6 | 7 | `masstree-beta` may require huge pages to work. You can use the 8 | usertools bundled with DPDK source code to setup huge pages on Linux. 9 | (no need to actually install DPDK.) 10 | ``` 11 | sudo dpdk-stable-20.11.1/usertools/dpdk-hugepages.py -p 2M --setup 2G 12 | ``` 13 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/masstree_analytics/build.rs: -------------------------------------------------------------------------------- 1 | const PROTO: &str = "../proto/masstree_analytics/masstree_analytics.proto"; 2 | 3 | fn main() -> Result<(), Box> { 4 | // Builds the project in the directory located in `libmt_index`, installing it 5 | // into $OUT_DIR 6 | let dst = cmake::build("libmt_index"); 7 | 8 | println!("cargo:rustc-link-search=native={}", dst.display()); 9 | println!("cargo:rustc-link-lib=static=mt_index"); 10 | 11 | // Generate code for proto 12 | println!("cargo:rerun-if-changed={PROTO}"); 13 | mrpc_build::compile_protos(PROTO)?; 14 | Ok(()) 15 | } 16 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/masstree_analytics/libmt_index/capi.cc: -------------------------------------------------------------------------------- 1 | #include "capi.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | void* mt_index_create() { return new MtIndex(); } 8 | 9 | void mt_index_destroy(void* obj) { delete static_cast(obj); } 10 | 11 | void mt_index_setup(void* obj, void* ti) { 12 | static_cast(obj)->setup(static_cast(ti)); 13 | } 14 | 15 | void mt_index_put(void* obj, size_t key, size_t value, void* ti) { 16 | static_cast(obj)->put(key, value, static_cast(ti)); 17 | } 18 | 19 | bool mt_index_get(void* obj, size_t key, size_t* value, void* ti) { 20 | return static_cast(obj)->get(key, *value, 21 | static_cast(ti)); 22 | } 23 | 24 | size_t mt_index_sum_in_range(void* obj, size_t cur_key, size_t range, 25 | void* ti) { 26 | return static_cast(obj)->sum_in_range( 27 | cur_key, range, static_cast(ti)); 28 | } 29 | 30 | void* threadinfo_make(int purpose, int index) { 31 | return threadinfo::make(purpose, index); 32 | } 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/masstree_analytics/libmt_index/capi.h: -------------------------------------------------------------------------------- 1 | #ifndef CAPI_H_ 2 | #define CAPI_H_ 3 | #include 4 | 5 | #include "mt_index_api.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | // MtIndex API 11 | void* mt_index_create(); 12 | void mt_index_destroy(void* obj); 13 | void mt_index_setup(void* obj, void* ti); 14 | void mt_index_put(void* obj, size_t key, size_t value, void* ti); 15 | bool mt_index_get(void* obj, size_t key, size_t* value, void* ti); 16 | size_t mt_index_sum_in_range(void* obj, size_t cur_key, size_t range, void* ti); 17 | 18 | // threadinfo API 19 | void* threadinfo_make(int purpose, int index); 20 | enum threadinfo_purpose { TI_MAIN, TI_PROCESS, TI_LOG, TI_CHECKPOINT }; 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | 26 | #endif // CAPI_H_ 27 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/masstree_analytics/libmt_index/mt_index_api.cc: -------------------------------------------------------------------------------- 1 | #include "mt_index_api.h" 2 | 3 | volatile uint64_t globalepoch = 1; 4 | volatile uint64_t active_epoch = 1; 5 | volatile bool recovering = false; 6 | kvtimestamp_t initial_timestamp; 7 | kvepoch_t global_log_epoch = 0; 8 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/masstree_analytics/libmt_index/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(test_mt_index test_mt_index.cc) 2 | include_directories(test_mt_index ${mt_index_INCLUDE_DIR_L}) 3 | link_directories(test_mt_index ${mt_index_LIBRARY_DIRS_L}) 4 | target_link_libraries(test_mt_index ${mt_index_LINKER_LIBS_L}) 5 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/masstree_analytics/libmt_index/test/test_mt_index.cc: -------------------------------------------------------------------------------- 1 | #include "capi.h" 2 | 3 | int main() { 4 | auto mt_index = mt_index_create(); 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/masstree_analytics/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod ffi; 2 | pub mod mt_index; 3 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/masstree_analytics/src/logging.rs: -------------------------------------------------------------------------------- 1 | pub fn init_env_log(filter_env: &str, default_level: &str) { 2 | use chrono::Utc; 3 | use std::io::Write; 4 | 5 | let env = env_logger::Env::new().filter_or(filter_env, default_level); 6 | env_logger::Builder::from_env(env) 7 | .format(|buf, record| { 8 | let level_style = buf.default_level_style(record.level()); 9 | writeln!( 10 | buf, 11 | "[{} {} {}:{}] {}", 12 | Utc::now().format("%Y-%m-%d %H:%M:%S%.6f"), 13 | level_style.value(record.level()), 14 | record.file().unwrap_or(""), 15 | record.line().unwrap_or(0), 16 | &record.args() 17 | ) 18 | }) 19 | .init(); 20 | 21 | log::info!("env_logger initialized"); 22 | } 23 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/proto/hotel_microservices/geo.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package geo; 4 | 5 | service Geo { 6 | // Finds the hotels contained nearby the current lat/lon. 7 | rpc Nearby(Request) returns (Result); 8 | } 9 | 10 | // The latitude and longitude of the current location. 11 | message Request { 12 | float lat = 1; 13 | float lon = 2; 14 | } 15 | 16 | message Result { 17 | repeated string hotelIds = 1; 18 | } 19 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/proto/hotel_microservices/profile.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package profile; 4 | 5 | service Profile { 6 | rpc GetProfiles(Request) returns (Result); 7 | } 8 | 9 | message Request { 10 | repeated string hotelIds = 1; 11 | string locale = 2; 12 | } 13 | 14 | message Result { 15 | repeated Hotel hotels = 1; 16 | } 17 | 18 | message Hotel { 19 | string id = 1; 20 | string name = 2; 21 | string phoneNumber = 3; 22 | string description = 4; 23 | Address address = 5; 24 | repeated Image images = 6; 25 | } 26 | 27 | message Address { 28 | string streetNumber = 1; 29 | string streetName = 2; 30 | string city = 3; 31 | string state = 4; 32 | string country = 5; 33 | string postalCode = 6; 34 | float lat = 7; 35 | float lon = 8; 36 | } 37 | 38 | message Image { 39 | string url = 1; 40 | bool default = 2; 41 | } 42 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/proto/hotel_microservices/rate.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package rate; 4 | 5 | service Rate { 6 | // GetRates returns rate codes for hotels for a given date range 7 | rpc GetRates(Request) returns (Result); 8 | } 9 | 10 | message Request { 11 | repeated string hotelIds = 1; 12 | string inDate = 2; 13 | string outDate = 3; 14 | } 15 | 16 | message Result { 17 | repeated RatePlan ratePlans = 1; 18 | } 19 | 20 | message RatePlan { 21 | string hotelId = 1; 22 | string code = 2; 23 | string inDate = 3; 24 | string outDate = 4; 25 | RoomType roomType = 5; 26 | } 27 | 28 | message RoomType { 29 | double bookableRate = 1; 30 | double totalRate = 2; 31 | double totalRateInclusive = 3; 32 | string code = 4; 33 | string currency = 5; 34 | string roomDescription = 6; 35 | } 36 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/proto/hotel_microservices/search.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package search; 4 | 5 | // Search service returns best hotel chocies for a user. 6 | service Search { 7 | rpc Nearby(NearbyRequest) returns (SearchResult); 8 | // rpc City(CityRequest) returns (SearchResult); 9 | } 10 | 11 | message NearbyRequest { 12 | float lat = 1; 13 | float lon = 2; 14 | string inDate = 3; 15 | string outDate = 4; 16 | } 17 | 18 | // TODO(hw): add city search endpoint 19 | // message CityRequest { 20 | // string city = 1; 21 | // string inDate = 2; 22 | // string outDate = 3; 23 | // } 24 | 25 | message SearchResult { 26 | repeated string hotelIds = 1; 27 | } 28 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/proto/reservation/reservation.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package reservation; 4 | 5 | service Reservation { 6 | // MakeReservation makes a reservation based on given information 7 | rpc MakeReservation(Request) returns (Result); 8 | // CheckAvailability checks if given information is available 9 | rpc CheckAvailability(Request) returns (Result); 10 | } 11 | 12 | message Request { 13 | string customerName = 1; 14 | repeated string hotelId = 2; 15 | string inDate = 3; 16 | string outDate = 4; 17 | int32 roomNumber = 5; 18 | } 19 | 20 | message Result { 21 | repeated string hotelId = 1; 22 | } 23 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/proto/rpc_hello/rpc_hello.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015 gRPC authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package rpc_hello; 18 | 19 | // The greeting service definition. 20 | service Greeter { 21 | // Sends a greeting 22 | rpc SayHello (HelloRequest) returns (HelloReply) {} 23 | } 24 | 25 | // The request message containing the user's name. 26 | message HelloRequest { 27 | bytes name = 1; 28 | } 29 | 30 | // The response message containing the greetings 31 | message HelloReply { 32 | bytes message = 1; 33 | } 34 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/proto/rpc_plus/rpc_plus.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015 gRPC authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package rpc_plus; 18 | 19 | // The greeting service definition. 20 | service Greeter { 21 | // Sends a greeting 22 | rpc SayHello (HelloRequest) returns (HelloReply) {} 23 | } 24 | 25 | // The request message containing the user's name. 26 | message HelloRequest { 27 | bytes key = 1; 28 | bytes payload = 2; 29 | bytes len = 3; 30 | } 31 | 32 | // The response message containing the greetings 33 | message HelloReply { 34 | bytes message = 1; 35 | } 36 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/rpc_bench/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rpc_bench" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [build-dependencies] 9 | mrpc-build.workspace = true 10 | 11 | [dependencies] 12 | mrpc.workspace = true 13 | prost = { workspace = true, features = ["mrpc-frontend"] } 14 | 15 | structopt.workspace = true 16 | tracing.workspace = true 17 | tracing-subscriber = { workspace = true, features = ["env-filter"] } 18 | tracing-appender.workspace = true 19 | futures.workspace = true 20 | smol.workspace = true 21 | minstant.workspace = true 22 | hdrhistogram.workspace = true 23 | scheduler.workspace = true 24 | libnuma.workspace = true 25 | 26 | 27 | [[bin]] 28 | name = "rpc_bench_client" 29 | path = "src/client.rs" 30 | 31 | [[bin]] 32 | name = "rpc_bench_server" 33 | path = "src/server.rs" 34 | 35 | [[bin]] 36 | name = "rpc_bench_brusty_client" 37 | path = "src/brusty_client.rs" 38 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/rpc_bench/build.rs: -------------------------------------------------------------------------------- 1 | const PROTO: &str = "../proto/rpc_hello/rpc_hello.proto"; 2 | fn main() -> Result<(), Box> { 3 | println!("cargo:rerun-if-changed={PROTO}"); 4 | mrpc_build::compile_protos(PROTO)?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/rpc_bench_plus/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rpc_bench_plus" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [build-dependencies] 9 | mrpc-build.workspace = true 10 | 11 | [dependencies] 12 | mrpc.workspace = true 13 | prost = { workspace = true, features = ["mrpc-frontend"] } 14 | 15 | structopt.workspace = true 16 | tracing.workspace = true 17 | tracing-subscriber = { workspace = true, features = ["env-filter"] } 18 | tracing-appender.workspace = true 19 | futures.workspace = true 20 | smol.workspace = true 21 | minstant.workspace = true 22 | hdrhistogram.workspace = true 23 | 24 | 25 | [[bin]] 26 | name = "rpc_bench_plus_client" 27 | path = "src/client.rs" 28 | 29 | [[bin]] 30 | name = "rpc_bench_plus_server" 31 | path = "src/server.rs" 32 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/rpc_bench_plus/build.rs: -------------------------------------------------------------------------------- 1 | const PROTO: &str = "../proto/rpc_plus/rpc_plus.proto"; 2 | fn main() -> Result<(), Box> { 3 | println!("cargo:rerun-if-changed={PROTO}"); 4 | mrpc_build::compile_protos(PROTO)?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/rpc_echo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rpc_echo" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [build-dependencies] 9 | mrpc-build.workspace = true 10 | 11 | [dependencies] 12 | mrpc.workspace = true 13 | prost = { workspace = true, features = ["mrpc-frontend"] } 14 | 15 | structopt.workspace = true 16 | smol.workspace = true 17 | 18 | 19 | [[bin]] 20 | name = "rpc_echo_frontend" 21 | path = "src/frontend.rs" 22 | 23 | [[bin]] 24 | name = "rpc_echo_server" 25 | path = "src/server.rs" 26 | 27 | [[bin]] 28 | name = "rpc_echo_client" 29 | path = "src/client.rs" 30 | 31 | [[bin]] 32 | name = "rpc_echo_client2" 33 | path = "src/client2.rs" 34 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/rpc_echo/README.md: -------------------------------------------------------------------------------- 1 | ## Build the application 2 | 3 | ```bash 4 | # In phoenix/experimental/mrpc 5 | cargo build --release --workspace -p rpc_hello_frontend 6 | ``` 7 | 8 | ## Run the application with client 9 | 10 | ```bash 11 | cargo rr -p rpc_echo --bin rpc_echo_server 12 | # In a seperate terminal 13 | cargo rr -p rpc_echo --bin rpc_echo_client 14 | ``` 15 | 16 | ## Run the application with frontend 17 | 18 | ```bash 19 | cargo rr -p rpc_echo --bin rpc_echo_server 20 | # In a seperate terminal 21 | cargo rr -p rpc_echo --bin rpc_echo_frontend 22 | # In a seperate terminal 23 | curl http://127.0.0.1:7878/hello 24 | ``` -------------------------------------------------------------------------------- /experimental/mrpc/examples/rpc_echo/build.rs: -------------------------------------------------------------------------------- 1 | const PROTO: &str = "../proto/rpc_hello/rpc_hello.proto"; 2 | fn main() -> Result<(), Box> { 3 | println!("cargo:rerun-if-changed={PROTO}"); 4 | mrpc_build::compile_protos(PROTO)?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /experimental/mrpc/examples/rpc_echo/src/client.rs: -------------------------------------------------------------------------------- 1 | pub mod rpc_hello { 2 | // The string specified here must match the proto package name 3 | mrpc::include_proto!("rpc_hello"); 4 | // include!("../../../mrpc/src/codegen.rs"); 5 | } 6 | 7 | use rpc_hello::greeter_client::GreeterClient; 8 | use rpc_hello::HelloRequest; 9 | 10 | fn main() -> Result<(), Box> { 11 | let client = GreeterClient::connect("localhost:5000")?; 12 | let req = HelloRequest { 13 | name: "mRPC".into(), 14 | }; 15 | let reply = smol::block_on(client.say_hello(req))?; 16 | println!("reply: {}", String::from_utf8_lossy(&reply.message)); 17 | Ok(()) 18 | } 19 | -------------------------------------------------------------------------------- /experimental/mrpc/mrpc-build/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mrpc-build" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [package.metadata.docs.rs] 9 | all-features = true 10 | 11 | [dependencies] 12 | prost-build = { workspace = true, features = ["mrpc-frontend"] } 13 | 14 | prettyplease.workspace = true 15 | proc-macro2.workspace = true 16 | quote.workspace = true 17 | syn.workspace = true 18 | crc32fast.workspace = true 19 | -------------------------------------------------------------------------------- /experimental/mrpc/mrpc-derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mrpc-derive" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | 7 | [lib] 8 | proc_macro = true 9 | 10 | [dependencies] 11 | anyhow.workspace = true 12 | itertools.workspace = true 13 | proc-macro2.workspace = true 14 | quote.workspace = true 15 | syn = { workspace = true, features = [ "extra-traits" ] } 16 | thiserror.workspace = true 17 | -------------------------------------------------------------------------------- /experimental/mrpc/mrpc-marshal/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mrpc-marshal" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | shm.workspace = true 10 | 11 | serde.workspace = true 12 | thiserror.workspace = true 13 | spin.workspace = true 14 | -------------------------------------------------------------------------------- /experimental/mrpc/mrpc-marshal/src/emplacement/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused)] 2 | #![allow(clippy::missing_safety_doc)] 3 | 4 | pub mod bytes; 5 | pub mod message; 6 | mod numeric; 7 | pub mod string; 8 | 9 | pub use numeric::{bool, double, float, int32, int64, uint32, uint64}; 10 | -------------------------------------------------------------------------------- /experimental/mrpc/mrpc-marshal/src/shadow/mod.rs: -------------------------------------------------------------------------------- 1 | //! Shadow data types have identical memory layouts with mRPC data types in the 2 | //! userland library, but they expose the details for marshaling and only 3 | //! implement minimal necessary functions. 4 | 5 | pub mod raw_vec; 6 | 7 | pub mod vec; 8 | pub use vec::Vec; 9 | 10 | pub mod string; 11 | pub use string::String; 12 | -------------------------------------------------------------------------------- /experimental/mrpc/mrpc-marshal/src/shadow/raw_vec.rs: -------------------------------------------------------------------------------- 1 | use shm::ptr::ShmPtr; 2 | 3 | pub struct RawVec { 4 | pub ptr: ShmPtr, 5 | pub cap: usize, 6 | } 7 | -------------------------------------------------------------------------------- /experimental/mrpc/mrpc-marshal/src/shadow/string.rs: -------------------------------------------------------------------------------- 1 | use super::vec::Vec; 2 | use std::fmt; 3 | use std::ops; 4 | use std::str; 5 | 6 | pub struct String { 7 | pub buf: Vec, 8 | } 9 | // pub use shm::string::String; 10 | 11 | impl fmt::Debug for String { 12 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 13 | fmt::Debug::fmt(&**self, f) 14 | } 15 | } 16 | 17 | // TODO(cjr): Maybe enforce Copy-on-access semantic here. 18 | impl ops::Deref for String { 19 | type Target = str; 20 | 21 | #[inline] 22 | fn deref(&self) -> &str { 23 | unsafe { str::from_utf8_unchecked(&self.buf) } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/load_balancer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-load-balancer" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api.workspace = true 10 | 11 | serde = { workspace = true, features = ["derive"] } 12 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/load_balancer/src/control_plane.rs: -------------------------------------------------------------------------------- 1 | use std::net::SocketAddr; 2 | 3 | use phoenix_api::Handle; 4 | use serde::{Deserialize, Serialize}; 5 | 6 | type IResult = Result; 7 | 8 | #[derive(Debug, Clone, Serialize, Deserialize)] 9 | pub enum Request { 10 | ListConnection, 11 | } 12 | 13 | #[derive(Debug, Clone, Serialize, Deserialize)] 14 | pub struct Connection { 15 | pub sock: Handle, 16 | pub local: SocketAddr, 17 | pub peer: SocketAddr, 18 | } 19 | 20 | #[derive(Debug, Clone, Serialize, Deserialize)] 21 | pub enum ResponseKind { 22 | ListConnection(Vec), 23 | } 24 | 25 | #[derive(Debug, Serialize, Deserialize)] 26 | pub struct Response(pub IResult); 27 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/load_balancer/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod control_plane; 2 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/mrpc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-mrpc" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api = { workspace = true, features = ["mrpc"] } 10 | 11 | serde.workspace = true 12 | static_assertions.workspace = true 13 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/mrpc/src/dp.rs: -------------------------------------------------------------------------------- 1 | //! mRPC data path operations. 2 | use serde::{Deserialize, Serialize}; 3 | 4 | use phoenix_api::rpc::{CallId, MessageErased, RpcId, TransportStatus}; 5 | use phoenix_api::Handle; 6 | 7 | pub type WorkRequestSlot = [u8; 64]; 8 | 9 | pub const RECV_RECLAIM_BS: usize = 4; 10 | 11 | #[repr(C, align(64))] 12 | #[derive(Debug, Clone, Copy, Serialize, Deserialize)] 13 | pub enum WorkRequest { 14 | Call(MessageErased), 15 | // this will also deallocate 16 | Reply(MessageErased), 17 | // conn_id and an array of call_id 18 | ReclaimRecvBuf(Handle, [CallId; RECV_RECLAIM_BS]), 19 | } 20 | 21 | pub type CompletionSlot = [u8; 64]; 22 | 23 | // Avoid using too much `Send`/`Recv` in the code. 24 | #[repr(C, align(64))] 25 | #[derive(Debug, Clone)] 26 | pub enum Completion { 27 | Incoming(MessageErased), 28 | Outgoing(RpcId, TransportStatus), 29 | // (conn_id, status) 30 | RecvError(Handle, TransportStatus), 31 | } 32 | 33 | mod sa { 34 | use super::*; 35 | use static_assertions::const_assert; 36 | use std::mem::size_of; 37 | const_assert!(size_of::() <= size_of::()); 38 | const_assert!(size_of::() <= size_of::()); 39 | } 40 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/mrpc/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod cmd; 2 | pub mod control_plane; 3 | pub mod dp; 4 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/mrpclb/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-mrpclb" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api = { workspace = true, features = ["mrpc"] } 10 | 11 | serde.workspace = true 12 | static_assertions.workspace = true 13 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/mrpclb/src/dp.rs: -------------------------------------------------------------------------------- 1 | //! mRPC data path operations. 2 | use serde::{Deserialize, Serialize}; 3 | 4 | use phoenix_api::rpc::{CallId, MessageErased, RpcId, TransportStatus}; 5 | use phoenix_api::Handle; 6 | 7 | pub type WorkRequestSlot = [u8; 64]; 8 | 9 | pub const RECV_RECLAIM_BS: usize = 4; 10 | 11 | #[repr(C, align(64))] 12 | #[derive(Debug, Clone, Copy, Serialize, Deserialize)] 13 | pub enum WorkRequest { 14 | Call(MessageErased), 15 | // this will also deallocate 16 | Reply(MessageErased), 17 | // conn_id and an array of call_id 18 | ReclaimRecvBuf(Handle, [CallId; RECV_RECLAIM_BS]), 19 | } 20 | 21 | pub type CompletionSlot = [u8; 64]; 22 | 23 | // Avoid using too much `Send`/`Recv` in the code. 24 | #[repr(C, align(64))] 25 | #[derive(Debug, Clone)] 26 | pub enum Completion { 27 | Incoming(MessageErased), 28 | Outgoing(RpcId, TransportStatus), 29 | // (conn_id, status) 30 | RecvError(Handle, TransportStatus), 31 | } 32 | 33 | mod sa { 34 | use super::*; 35 | use static_assertions::const_assert; 36 | use std::mem::size_of; 37 | const_assert!(size_of::() <= size_of::()); 38 | const_assert!(size_of::() <= size_of::()); 39 | } 40 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/mrpclb/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod cmd; 2 | pub mod control_plane; 3 | pub mod dp; 4 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/hello-acl-receiver/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-policy-hello-acl-receiver" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api.workspace = true 10 | 11 | serde.workspace = true 12 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/hello-acl-receiver/src/control_plane.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | type IResult = Result; 4 | 5 | #[derive(Debug, Clone, Serialize, Deserialize)] 6 | pub enum Request { 7 | NewConfig, 8 | } 9 | 10 | #[derive(Debug, Clone, Serialize, Deserialize)] 11 | pub enum ResponseKind {} 12 | 13 | #[derive(Debug, Serialize, Deserialize)] 14 | pub struct Response(pub IResult); 15 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/hello-acl-receiver/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod control_plane; 2 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/hello-acl-sender/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-policy-hello-acl-sender" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api.workspace = true 10 | 11 | serde.workspace = true 12 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/hello-acl-sender/src/control_plane.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | type IResult = Result; 4 | 5 | #[derive(Debug, Clone, Serialize, Deserialize)] 6 | pub enum Request { 7 | NewConfig, 8 | } 9 | 10 | #[derive(Debug, Clone, Serialize, Deserialize)] 11 | pub enum ResponseKind {} 12 | 13 | #[derive(Debug, Serialize, Deserialize)] 14 | pub struct Response(pub IResult); 15 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/hello-acl-sender/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod control_plane; 2 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/hotel-acl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-policy-hotel-acl" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api.workspace = true 10 | 11 | serde.workspace = true 12 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/hotel-acl/src/control_plane.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | type IResult = Result; 4 | 5 | #[derive(Debug, Clone, Serialize, Deserialize)] 6 | pub enum Request { 7 | NewConfig, 8 | } 9 | 10 | #[derive(Debug, Clone, Serialize, Deserialize)] 11 | pub enum ResponseKind {} 12 | 13 | #[derive(Debug, Serialize, Deserialize)] 14 | pub struct Response(pub IResult); 15 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/hotel-acl/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod control_plane; 2 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/logging/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-policy-logging" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api.workspace = true 10 | 11 | serde.workspace = true 12 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/logging/src/control_plane.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | type IResult = Result; 4 | 5 | #[derive(Debug, Clone, Serialize, Deserialize)] 6 | pub enum Request { 7 | NewConfig(), 8 | } 9 | 10 | #[derive(Debug, Clone, Serialize, Deserialize)] 11 | pub enum ResponseKind {} 12 | 13 | #[derive(Debug, Serialize, Deserialize)] 14 | pub struct Response(pub IResult); 15 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/logging/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod control_plane; 2 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/null/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-policy-null" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api.workspace = true 10 | 11 | serde.workspace = true 12 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/null/src/control_plane.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | type IResult = Result; 4 | 5 | #[derive(Debug, Clone, Serialize, Deserialize)] 6 | pub enum Request { 7 | NewConfig(), 8 | } 9 | 10 | #[derive(Debug, Clone, Serialize, Deserialize)] 11 | pub enum ResponseKind {} 12 | 13 | #[derive(Debug, Serialize, Deserialize)] 14 | pub struct Response(pub IResult); 15 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/null/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod control_plane; 2 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/qos/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-policy-qos" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api.workspace = true 10 | 11 | serde.workspace = true 12 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/qos/src/control_plane.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | type IResult = Result; 4 | 5 | #[derive(Debug, Clone, Serialize, Deserialize)] 6 | pub enum Request { 7 | NewConfig(u64), 8 | } 9 | 10 | #[derive(Debug, Clone, Serialize, Deserialize)] 11 | pub enum ResponseKind {} 12 | 13 | #[derive(Debug, Serialize, Deserialize)] 14 | pub struct Response(pub IResult); 15 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/qos/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod control_plane; 2 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/ratelimit/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-policy-ratelimit" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api.workspace = true 10 | 11 | serde.workspace = true 12 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/ratelimit/src/control_plane.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | type IResult = Result; 4 | 5 | #[derive(Debug, Clone, Serialize, Deserialize)] 6 | pub enum Request { 7 | NewConfig(u64, u64), 8 | } 9 | 10 | #[derive(Debug, Clone, Serialize, Deserialize)] 11 | pub enum ResponseKind {} 12 | 13 | #[derive(Debug, Serialize, Deserialize)] 14 | pub struct Response(pub IResult); 15 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/policy/ratelimit/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod control_plane; 2 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/rpc_adapter/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-rpc-adapter" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api.workspace = true 10 | 11 | serde = { workspace = true, features = ["derive"] } 12 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/rpc_adapter/src/control_plane.rs: -------------------------------------------------------------------------------- 1 | use std::net::SocketAddr; 2 | 3 | use serde::{Deserialize, Serialize}; 4 | 5 | type IResult = Result; 6 | 7 | #[derive(Debug, Clone, Serialize, Deserialize)] 8 | pub enum Request { 9 | ListConnection, 10 | } 11 | 12 | #[derive(Debug, Clone, Serialize, Deserialize)] 13 | pub struct Connection { 14 | pub cmid: phoenix_api::net::CmId, 15 | pub local: SocketAddr, 16 | pub peer: SocketAddr, 17 | } 18 | 19 | #[derive(Debug, Clone, Serialize, Deserialize)] 20 | pub enum ResponseKind { 21 | ListConnection(Vec), 22 | } 23 | 24 | #[derive(Debug, Serialize, Deserialize)] 25 | pub struct Response(pub IResult); 26 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/rpc_adapter/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod control_plane; 2 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/tcp_rpc_adapter/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-api-tcp-rpc-adapter" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix-api.workspace = true 10 | 11 | serde = { workspace = true, features = ["derive"] } 12 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/tcp_rpc_adapter/src/control_plane.rs: -------------------------------------------------------------------------------- 1 | use std::net::SocketAddr; 2 | 3 | use phoenix_api::Handle; 4 | use serde::{Deserialize, Serialize}; 5 | 6 | type IResult = Result; 7 | 8 | #[derive(Debug, Clone, Serialize, Deserialize)] 9 | pub enum Request { 10 | ListConnection, 11 | } 12 | 13 | #[derive(Debug, Clone, Serialize, Deserialize)] 14 | pub struct Connection { 15 | pub sock: Handle, 16 | pub local: SocketAddr, 17 | pub peer: SocketAddr, 18 | } 19 | 20 | #[derive(Debug, Clone, Serialize, Deserialize)] 21 | pub enum ResponseKind { 22 | ListConnection(Vec), 23 | } 24 | 25 | #[derive(Debug, Serialize, Deserialize)] 26 | pub struct Response(pub IResult); 27 | -------------------------------------------------------------------------------- /experimental/mrpc/phoenix-api/tcp_rpc_adapter/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod control_plane; 2 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/load_balancer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-load-balancer" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | crate-type = ["rlib"] 10 | 11 | [dependencies] 12 | phoenix-api-mrpc.workspace = true 13 | phoenix-api-load-balancer.workspace = true 14 | phoenix-mrpc.workspace = true 15 | mrpc-marshal.workspace = true 16 | 17 | phoenix-api = { workspace = true, features = ["mrpc", "transport"] } 18 | ipc.workspace = true 19 | phoenix_common.workspace = true 20 | transport-tcp.workspace = true 21 | phoenix-salloc.workspace = true 22 | utils.workspace = true 23 | 24 | fnv.workspace = true 25 | anyhow.workspace = true 26 | tokio = { workspace = true, features = ["sync"] } 27 | thiserror.workspace = true 28 | nix.workspace = true 29 | futures.workspace = true 30 | dashmap.workspace = true 31 | spin.workspace = true 32 | libloading.workspace = true 33 | serde = { workspace = true, features = ["derive"] } 34 | toml = { workspace = true, features = ["preserve_order"] } 35 | fastrand.workspace = true 36 | bitvec.workspace = true 37 | bincode.workspace = true 38 | socket2.workspace = true 39 | slab.workspace = true 40 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-mrpc" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | crate-type = ["rlib"] 10 | 11 | [dependencies] 12 | phoenix-api-mrpc.workspace = true 13 | mrpc-marshal.workspace = true 14 | 15 | phoenix-api = { workspace = true, features = ["mrpc"] } 16 | ipc.workspace = true 17 | phoenix_common.workspace = true 18 | prost-build = { workspace = true, features = ["mrpc-backend"] } 19 | utils.workspace = true 20 | 21 | tokio = { workspace = true, features = ["sync"] } 22 | anyhow.workspace = true 23 | lazy_static.workspace = true 24 | fnv.workspace = true 25 | uuid.workspace = true 26 | futures.workspace = true 27 | thiserror.workspace = true 28 | itertools.workspace = true 29 | crc32fast.workspace = true 30 | fastrand.workspace = true 31 | syn.workspace = true 32 | quote.workspace = true 33 | proc-macro2.workspace = true 34 | md5.workspace = true 35 | prettyplease.workspace = true 36 | serde = { workspace = true, features = ["derive"] } 37 | serde_json.workspace = true 38 | toml = { workspace = true, features = ["preserve_order"] } 39 | static_assertions.workspace = true 40 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpc/src/builder/compiler/template/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dispatch" 3 | version = "1.0.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["dylib"] 8 | 9 | [dependencies] 10 | mrpc-derive = {{ path = "{mrpc_derive}" }} 11 | mrpc-marshal = {{ path = "{mrpc_marshal}" }} 12 | shm = {{ path = "{shm}" }} 13 | phoenix-api = {{ path = "{phoenix_api}", features = ["mrpc"] }} 14 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpc/src/builder/prost/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::module_inception)] 2 | use thiserror::Error; 3 | 4 | pub mod prost; 5 | pub mod service; 6 | 7 | pub use prost::Builder; 8 | pub use prost::{compile_protos, configure}; 9 | 10 | #[derive(Error, Debug)] 11 | pub enum Error { 12 | #[error("IO Error: {0}")] 13 | IO(#[from] std::io::Error), 14 | #[error("Serde JSON Error: {0}")] 15 | SerdeJSON(#[from] serde_json::Error), 16 | } 17 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpc/src/config.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use phoenix_api_mrpc::control_plane::TransportType; 4 | use serde::{Deserialize, Serialize}; 5 | 6 | #[derive(Debug, Clone, Serialize, Deserialize)] 7 | #[serde(deny_unknown_fields)] 8 | pub struct MrpcConfig { 9 | /// Prefix for the control socket 10 | #[serde(default)] 11 | pub prefix: Option, 12 | /// Base name of the control socket 13 | #[serde(default = "default_engine_basename")] 14 | pub engine_basename: String, 15 | /// The directory to store the build cache 16 | #[serde(default = "default_build_cache")] 17 | pub build_cache: PathBuf, 18 | /// Transport to use 19 | pub transport: TransportType, 20 | /// Use NIC 0 by default 21 | #[serde(default)] 22 | pub nic_index: usize, 23 | } 24 | 25 | impl MrpcConfig { 26 | pub fn new(config: Option<&str>) -> anyhow::Result { 27 | let config = toml::from_str(config.unwrap_or(""))?; 28 | Ok(config) 29 | } 30 | } 31 | 32 | fn default_build_cache() -> PathBuf { 33 | // A path relative to MrpcConfig::prefix if it's non-empty or phoenix_prefix. 34 | PathBuf::from("build_cache") 35 | } 36 | 37 | fn default_engine_basename() -> String { 38 | "mrpc-engine".to_owned() 39 | } 40 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpc/src/state.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::sync::Arc; 3 | 4 | use phoenix_common::state_mgr::{Pid, ProcessShared}; 5 | 6 | pub(crate) struct State { 7 | pub(crate) _shared: Arc, 8 | } 9 | 10 | impl State { 11 | pub(crate) fn new(shared: Arc) -> Self { 12 | State { _shared: shared } 13 | } 14 | } 15 | 16 | #[allow(clippy::manual_non_exhaustive)] 17 | pub struct Shared { 18 | pub pid: Pid, 19 | _other_state: (), 20 | } 21 | 22 | impl ProcessShared for Shared { 23 | type Err = io::Error; 24 | 25 | fn new(pid: Pid) -> io::Result { 26 | let shared = Shared { 27 | pid, 28 | _other_state: (), 29 | }; 30 | Ok(shared) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpc/src/unpack.rs: -------------------------------------------------------------------------------- 1 | use std::ptr::Unique; 2 | 3 | use mrpc_marshal::{SgE, UnmarshalError}; 4 | use phoenix_api::rpc::MessageMeta; 5 | 6 | pub trait UnpackFromSgE: Sized { 7 | /// # Safety 8 | /// 9 | /// This operation may be zero-copy. Thus, the user must ensure the underlying data remain 10 | /// valid after unpacking. 11 | unsafe fn unpack(sge: &SgE) -> Result, UnmarshalError>; 12 | } 13 | 14 | impl UnpackFromSgE for MessageMeta { 15 | unsafe fn unpack(sge: &SgE) -> Result, UnmarshalError> { 16 | if sge.len != std::mem::size_of::() { 17 | return Err(UnmarshalError::SgELengthMismatch { 18 | expected: std::mem::size_of::(), 19 | actual: sge.len, 20 | }); 21 | } 22 | let ptr = sge.ptr as *mut Self; 23 | let meta = Unique::new(ptr).unwrap(); 24 | Ok(meta) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpclb/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-mrpclb" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | crate-type = ["rlib"] 10 | 11 | [dependencies] 12 | phoenix-api-mrpc.workspace = true 13 | mrpc-marshal.workspace = true 14 | 15 | phoenix-api = { workspace = true, features = ["mrpc"] } 16 | ipc.workspace = true 17 | phoenix_common.workspace = true 18 | prost-build = { workspace = true, features = ["mrpc-backend"] } 19 | utils.workspace = true 20 | 21 | tokio = { workspace = true, features = ["sync"] } 22 | anyhow.workspace = true 23 | lazy_static.workspace = true 24 | fnv.workspace = true 25 | uuid.workspace = true 26 | futures.workspace = true 27 | thiserror.workspace = true 28 | itertools.workspace = true 29 | crc32fast.workspace = true 30 | fastrand.workspace = true 31 | syn.workspace = true 32 | quote.workspace = true 33 | proc-macro2.workspace = true 34 | md5.workspace = true 35 | prettyplease.workspace = true 36 | serde = { workspace = true, features = ["derive"] } 37 | serde_json.workspace = true 38 | toml = { workspace = true, features = ["preserve_order"] } 39 | static_assertions.workspace = true 40 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpclb/src/builder/compiler/template/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dispatch" 3 | version = "1.0.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["dylib"] 8 | 9 | [dependencies] 10 | mrpc-derive = {{ path = "{mrpc_derive}" }} 11 | mrpc-marshal = {{ path = "{mrpc_marshal}" }} 12 | shm = {{ path = "{shm}" }} 13 | phoenix-api = {{ path = "{phoenix_api}", features = ["mrpc"] }} 14 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpclb/src/builder/prost/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::module_inception)] 2 | use thiserror::Error; 3 | 4 | pub mod prost; 5 | pub mod service; 6 | 7 | pub use prost::Builder; 8 | pub use prost::{compile_protos, configure}; 9 | 10 | #[derive(Error, Debug)] 11 | pub enum Error { 12 | #[error("IO Error: {0}")] 13 | IO(#[from] std::io::Error), 14 | #[error("Serde JSON Error: {0}")] 15 | SerdeJSON(#[from] serde_json::Error), 16 | } 17 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpclb/src/config.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use phoenix_api_mrpc::control_plane::TransportType; 4 | use serde::{Deserialize, Serialize}; 5 | 6 | #[derive(Debug, Clone, Serialize, Deserialize)] 7 | #[serde(deny_unknown_fields)] 8 | pub struct MrpcLBConfig { 9 | /// Prefix for the control socket 10 | #[serde(default)] 11 | pub prefix: Option, 12 | /// Base name of the control socket 13 | #[serde(default = "default_engine_basename")] 14 | pub engine_basename: String, 15 | /// The directory to store the build cache 16 | #[serde(default = "default_build_cache")] 17 | pub build_cache: PathBuf, 18 | /// Transport to use 19 | pub transport: TransportType, 20 | /// Use NIC 0 by default 21 | #[serde(default)] 22 | pub nic_index: usize, 23 | } 24 | 25 | impl MrpcLBConfig { 26 | pub fn new(config: Option<&str>) -> anyhow::Result { 27 | let config = toml::from_str(config.unwrap_or(""))?; 28 | Ok(config) 29 | } 30 | } 31 | 32 | fn default_build_cache() -> PathBuf { 33 | // A path relative to MrpcConfig::prefix if it's non-empty or phoenix_prefix. 34 | PathBuf::from("build_cache") 35 | } 36 | 37 | fn default_engine_basename() -> String { 38 | "mrpclb-engine".to_owned() 39 | } 40 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpclb/src/state.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::sync::Arc; 3 | 4 | use phoenix_common::state_mgr::{Pid, ProcessShared}; 5 | 6 | pub(crate) struct State { 7 | pub(crate) _shared: Arc, 8 | } 9 | 10 | impl State { 11 | pub(crate) fn new(shared: Arc) -> Self { 12 | State { _shared: shared } 13 | } 14 | } 15 | 16 | #[allow(clippy::manual_non_exhaustive)] 17 | pub struct Shared { 18 | pub pid: Pid, 19 | _other_state: (), 20 | } 21 | 22 | impl ProcessShared for Shared { 23 | type Err = io::Error; 24 | 25 | fn new(pid: Pid) -> io::Result { 26 | let shared = Shared { 27 | pid, 28 | _other_state: (), 29 | }; 30 | Ok(shared) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/mrpclb/src/unpack.rs: -------------------------------------------------------------------------------- 1 | use std::ptr::Unique; 2 | 3 | use mrpc_marshal::{SgE, UnmarshalError}; 4 | use phoenix_api::rpc::MessageMeta; 5 | 6 | pub trait UnpackFromSgE: Sized { 7 | /// # Safety 8 | /// 9 | /// This operation may be zero-copy. Thus, the user must ensure the underlying data remain 10 | /// valid after unpacking. 11 | unsafe fn unpack(sge: &SgE) -> Result, UnmarshalError>; 12 | } 13 | 14 | impl UnpackFromSgE for MessageMeta { 15 | unsafe fn unpack(sge: &SgE) -> Result, UnmarshalError> { 16 | if sge.len != std::mem::size_of::() { 17 | return Err(UnmarshalError::SgELengthMismatch { 18 | expected: std::mem::size_of::(), 19 | actual: sge.len, 20 | }); 21 | } 22 | let ptr = sge.ptr as *mut Self; 23 | let meta = Unique::new(ptr).unwrap(); 24 | Ok(meta) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/hello-acl-receiver/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-hello-acl-receiver" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | 9 | [dependencies] 10 | phoenix-api-policy-hello-acl-receiver.workspace = true 11 | mrpc-marshal.workspace = true 12 | mrpc-derive.workspace = true 13 | 14 | phoenix_common.workspace = true 15 | shm.workspace = true 16 | phoenix-api = { workspace = true, features = ["mrpc"] } 17 | 18 | futures.workspace = true 19 | minstant.workspace = true 20 | thiserror.workspace = true 21 | serde = { workspace = true, features = ["derive"] } 22 | serde_json.workspace = true 23 | anyhow.workspace = true 24 | nix.workspace = true 25 | toml = { workspace = true, features = ["preserve_order"] } 26 | bincode.workspace = true 27 | fnv.workspace = true 28 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/hello-acl-receiver/src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] 4 | #[serde(deny_unknown_fields)] 5 | pub struct HelloAclReceiverConfig {} 6 | 7 | impl HelloAclReceiverConfig { 8 | pub fn new(config: Option<&str>) -> anyhow::Result { 9 | let config = toml::from_str(config.unwrap_or(""))?; 10 | Ok(config) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/hello-acl-receiver/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(peer_credentials_unix_socket)] 2 | #![feature(ptr_internals)] 3 | #![feature(strict_provenance)] 4 | 5 | use thiserror::Error; 6 | 7 | pub use phoenix_common::{InitFnResult, PhoenixAddon}; 8 | 9 | pub mod config; 10 | pub(crate) mod engine; 11 | pub mod module; 12 | 13 | #[derive(Error, Debug)] 14 | pub(crate) enum DatapathError { 15 | #[error("Internal queue send error")] 16 | InternalQueueSend, 17 | } 18 | 19 | use phoenix_common::engine::datapath::SendError; 20 | impl From> for DatapathError { 21 | fn from(_other: SendError) -> Self { 22 | DatapathError::InternalQueueSend 23 | } 24 | } 25 | 26 | use crate::config::HelloAclReceiverConfig; 27 | use crate::module::HelloAclReceiverAddon; 28 | 29 | #[no_mangle] 30 | pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { 31 | let config = HelloAclReceiverConfig::new(config_string)?; 32 | let addon = HelloAclReceiverAddon::new(config); 33 | Ok(Box::new(addon)) 34 | } 35 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/hello-acl-receiver/src/rpc_hello.rs: -------------------------------------------------------------------------------- 1 | /// The request message containing the user's name. 2 | #[repr(C)] 3 | #[derive(Debug, Clone, ::mrpc_derive::Message)] 4 | pub struct HelloRequest { 5 | #[prost(bytes = "vec", tag = "1")] 6 | pub name: ::mrpc_marshal::shadow::Vec, 7 | } 8 | /// The response message containing the greetings 9 | #[repr(C)] 10 | #[derive(Debug, ::mrpc_derive::Message)] 11 | pub struct HelloReply { 12 | #[prost(bytes = "vec", tag = "1")] 13 | pub message: ::mrpc_marshal::shadow::Vec, 14 | } 15 | 16 | // /// The request message containing the user's name. 17 | // #[repr(C)] 18 | // #[derive(Debug, Clone, ::mrpc_derive::Message)] 19 | // pub struct HelloRequest { 20 | // #[prost(bytes = "vec", tag = "1")] 21 | // pub name: ::mrpc::alloc::Vec, 22 | // } 23 | // /// The response message containing the greetings 24 | // #[repr(C)] 25 | // #[derive(Debug, ::mrpc_derive::Message)] 26 | // pub struct HelloReply { 27 | // #[prost(bytes = "vec", tag = "1")] 28 | // pub message: ::mrpc::alloc::Vec, 29 | // } 30 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/hello-acl-sender/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-hello-acl-sender" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | 9 | [dependencies] 10 | phoenix-api-policy-hello-acl-sender.workspace = true 11 | mrpc-marshal.workspace = true 12 | mrpc-derive.workspace = true 13 | 14 | phoenix_common.workspace = true 15 | shm.workspace = true 16 | phoenix-api = { workspace = true, features = ["mrpc"] } 17 | 18 | futures.workspace = true 19 | minstant.workspace = true 20 | thiserror.workspace = true 21 | serde = { workspace = true, features = ["derive"] } 22 | serde_json.workspace = true 23 | anyhow.workspace = true 24 | nix.workspace = true 25 | toml = { workspace = true, features = ["preserve_order"] } 26 | bincode.workspace = true 27 | fnv.workspace = true 28 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/hello-acl-sender/src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] 4 | #[serde(deny_unknown_fields)] 5 | pub struct HelloAclSenderConfig {} 6 | 7 | impl HelloAclSenderConfig { 8 | pub fn new(config: Option<&str>) -> anyhow::Result { 9 | let config = toml::from_str(config.unwrap_or(""))?; 10 | Ok(config) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/hello-acl-sender/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(peer_credentials_unix_socket)] 2 | #![feature(ptr_internals)] 3 | #![feature(strict_provenance)] 4 | 5 | use thiserror::Error; 6 | 7 | pub use phoenix_common::{InitFnResult, PhoenixAddon}; 8 | 9 | pub mod config; 10 | pub(crate) mod engine; 11 | pub mod module; 12 | 13 | #[derive(Error, Debug)] 14 | pub(crate) enum DatapathError { 15 | #[error("Internal queue send error")] 16 | InternalQueueSend, 17 | } 18 | 19 | use phoenix_common::engine::datapath::SendError; 20 | impl From> for DatapathError { 21 | fn from(_other: SendError) -> Self { 22 | DatapathError::InternalQueueSend 23 | } 24 | } 25 | 26 | use crate::config::HelloAclSenderConfig; 27 | use crate::module::HelloAclSenderAddon; 28 | 29 | #[no_mangle] 30 | pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { 31 | let config = HelloAclSenderConfig::new(config_string)?; 32 | let addon = HelloAclSenderAddon::new(config); 33 | Ok(Box::new(addon)) 34 | } 35 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/hello-acl-sender/src/rpc_hello.rs: -------------------------------------------------------------------------------- 1 | /// The request message containing the user's name. 2 | #[repr(C)] 3 | #[derive(Debug, Clone, ::mrpc_derive::Message)] 4 | pub struct HelloRequest { 5 | #[prost(bytes = "vec", tag = "1")] 6 | pub name: ::mrpc_marshal::shadow::Vec, 7 | } 8 | /// The response message containing the greetings 9 | #[repr(C)] 10 | #[derive(Debug, ::mrpc_derive::Message)] 11 | pub struct HelloReply { 12 | #[prost(bytes = "vec", tag = "1")] 13 | pub message: ::mrpc_marshal::shadow::Vec, 14 | } 15 | 16 | // /// The request message containing the user's name. 17 | // #[repr(C)] 18 | // #[derive(Debug, Clone, ::mrpc_derive::Message)] 19 | // pub struct HelloRequest { 20 | // #[prost(bytes = "vec", tag = "1")] 21 | // pub name: ::mrpc::alloc::Vec, 22 | // } 23 | // /// The response message containing the greetings 24 | // #[repr(C)] 25 | // #[derive(Debug, ::mrpc_derive::Message)] 26 | // pub struct HelloReply { 27 | // #[prost(bytes = "vec", tag = "1")] 28 | // pub message: ::mrpc::alloc::Vec, 29 | // } 30 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/hotel-acl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-hotel-acl" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | 9 | [dependencies] 10 | phoenix-api-policy-hotel-acl.workspace = true 11 | mrpc-marshal.workspace = true 12 | mrpc-derive.workspace = true 13 | 14 | phoenix_common.workspace = true 15 | shm.workspace = true 16 | phoenix-api = { workspace = true, features = ["mrpc"] } 17 | 18 | futures.workspace = true 19 | minstant.workspace = true 20 | thiserror.workspace = true 21 | serde = { workspace = true, features = ["derive"] } 22 | serde_json.workspace = true 23 | anyhow.workspace = true 24 | nix.workspace = true 25 | toml = { workspace = true, features = ["preserve_order"] } 26 | bincode.workspace = true 27 | fnv.workspace = true 28 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/hotel-acl/src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] 4 | #[serde(deny_unknown_fields)] 5 | pub struct HotelAclConfig {} 6 | 7 | impl HotelAclConfig { 8 | pub fn new(config: Option<&str>) -> anyhow::Result { 9 | let config = toml::from_str(config.unwrap_or(""))?; 10 | Ok(config) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/hotel-acl/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(peer_credentials_unix_socket)] 2 | #![feature(ptr_internals)] 3 | #![feature(strict_provenance)] 4 | 5 | use thiserror::Error; 6 | 7 | pub use phoenix_common::{InitFnResult, PhoenixAddon}; 8 | 9 | pub mod config; 10 | pub(crate) mod engine; 11 | pub mod module; 12 | 13 | #[derive(Error, Debug)] 14 | pub(crate) enum DatapathError { 15 | #[error("Internal queue send error")] 16 | InternalQueueSend, 17 | } 18 | 19 | use phoenix_common::engine::datapath::SendError; 20 | impl From> for DatapathError { 21 | fn from(_other: SendError) -> Self { 22 | DatapathError::InternalQueueSend 23 | } 24 | } 25 | 26 | use crate::config::HotelAclConfig; 27 | use crate::module::HotelAclAddon; 28 | 29 | #[no_mangle] 30 | pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { 31 | let config = HotelAclConfig::new(config_string)?; 32 | let addon = HotelAclAddon::new(config); 33 | Ok(Box::new(addon)) 34 | } 35 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/logging/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-logging" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix_common.workspace = true 10 | phoenix-api-policy-logging.workspace = true 11 | 12 | futures.workspace = true 13 | minstant.workspace = true 14 | thiserror.workspace = true 15 | serde = { workspace = true, features = ["derive"] } 16 | serde_json.workspace = true 17 | anyhow.workspace = true 18 | nix.workspace = true 19 | toml = { workspace = true, features = ["preserve_order"] } 20 | bincode.workspace = true 21 | chrono.workspace = true 22 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/logging/src/config.rs: -------------------------------------------------------------------------------- 1 | use chrono::{Datelike, Timelike, Utc}; 2 | use phoenix_common::log; 3 | use serde::{Deserialize, Serialize}; 4 | 5 | #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] 6 | #[serde(deny_unknown_fields)] 7 | pub struct LoggingConfig {} 8 | 9 | impl LoggingConfig { 10 | pub fn new(config: Option<&str>) -> anyhow::Result { 11 | let config = toml::from_str(config.unwrap_or(""))?; 12 | Ok(config) 13 | } 14 | } 15 | 16 | pub fn create_log_file() -> std::fs::File { 17 | std::fs::create_dir_all("/tmp/phoenix/log").expect("mkdir failed"); 18 | let now = Utc::now(); 19 | let date_string = format!( 20 | "{}-{}-{}-{}-{}-{}", 21 | now.year(), 22 | now.month(), 23 | now.day(), 24 | now.hour(), 25 | now.minute(), 26 | now.second() 27 | ); 28 | let file_name = format!("/tmp/phoenix/log/logging_engine_{}.log", date_string); 29 | log::info!("create log file {}", file_name); 30 | let log_file = std::fs::File::create(file_name).expect("create file failed"); 31 | log_file 32 | } 33 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/logging/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(peer_credentials_unix_socket)] 2 | 3 | use thiserror::Error; 4 | 5 | pub use phoenix_common::{InitFnResult, PhoenixAddon}; 6 | 7 | pub mod config; 8 | pub(crate) mod engine; 9 | pub mod module; 10 | 11 | #[derive(Error, Debug)] 12 | pub(crate) enum DatapathError { 13 | #[error("Internal queue send error")] 14 | InternalQueueSend, 15 | } 16 | 17 | use phoenix_common::engine::datapath::SendError; 18 | impl From> for DatapathError { 19 | fn from(_other: SendError) -> Self { 20 | DatapathError::InternalQueueSend 21 | } 22 | } 23 | 24 | use crate::config::LoggingConfig; 25 | use crate::module::LoggingAddon; 26 | 27 | #[no_mangle] 28 | pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { 29 | let config = LoggingConfig::new(config_string)?; 30 | let addon = LoggingAddon::new(config); 31 | Ok(Box::new(addon)) 32 | } 33 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/null/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-null" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix_common.workspace = true 10 | phoenix-api-policy-null.workspace = true 11 | 12 | futures.workspace = true 13 | minstant.workspace = true 14 | thiserror.workspace = true 15 | serde = { workspace = true, features = ["derive"] } 16 | serde_json.workspace = true 17 | anyhow.workspace = true 18 | nix.workspace = true 19 | toml = { workspace = true, features = ["preserve_order"] } 20 | bincode.workspace = true 21 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/null/src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] 4 | #[serde(deny_unknown_fields)] 5 | pub struct NullConfig {} 6 | 7 | impl NullConfig { 8 | pub fn new(config: Option<&str>) -> anyhow::Result { 9 | let config = toml::from_str(config.unwrap_or(""))?; 10 | Ok(config) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/null/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(peer_credentials_unix_socket)] 2 | 3 | use thiserror::Error; 4 | 5 | pub use phoenix_common::{InitFnResult, PhoenixAddon}; 6 | 7 | pub mod config; 8 | pub(crate) mod engine; 9 | pub mod module; 10 | 11 | #[derive(Error, Debug)] 12 | pub(crate) enum DatapathError { 13 | #[error("Internal queue send error")] 14 | InternalQueueSend, 15 | } 16 | 17 | use phoenix_common::engine::datapath::SendError; 18 | impl From> for DatapathError { 19 | fn from(_other: SendError) -> Self { 20 | DatapathError::InternalQueueSend 21 | } 22 | } 23 | 24 | use crate::config::NullConfig; 25 | use crate::module::NullAddon; 26 | 27 | #[no_mangle] 28 | pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { 29 | let config = NullConfig::new(config_string)?; 30 | let addon = NullAddon::new(config); 31 | Ok(Box::new(addon)) 32 | } 33 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/qos/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-qos" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix_common.workspace = true 10 | phoenix-api-policy-qos.workspace = true 11 | 12 | futures.workspace = true 13 | minstant.workspace = true 14 | thiserror.workspace = true 15 | nix.workspace = true 16 | anyhow.workspace = true 17 | serde = { workspace = true, features = ["derive"] } 18 | toml = { workspace = true, features = ["preserve_order"] } 19 | bincode.workspace = true 20 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/qos/src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Debug, Clone, Copy, Serialize, Deserialize)] 4 | #[serde(deny_unknown_fields)] 5 | pub struct QosConfig { 6 | // (non-strict) latency budget 7 | pub latency_budget_microsecs: u64, 8 | } 9 | 10 | impl Default for QosConfig { 11 | fn default() -> Self { 12 | QosConfig { 13 | latency_budget_microsecs: 10, 14 | } 15 | } 16 | } 17 | 18 | impl QosConfig { 19 | pub fn new(config: Option<&str>) -> anyhow::Result { 20 | let config = toml::from_str(config.unwrap_or(""))?; 21 | Ok(config) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/qos/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(peer_credentials_unix_socket)] 2 | #![feature(local_key_cell_methods)] 3 | #![feature(extract_if)] 4 | 5 | use thiserror::Error; 6 | 7 | pub use phoenix_common::{InitFnResult, PhoenixAddon}; 8 | 9 | pub mod config; 10 | pub(crate) mod engine; 11 | pub mod module; 12 | 13 | #[derive(Error, Debug)] 14 | pub(crate) enum DatapathError { 15 | #[error("Internal queue send error")] 16 | InternalQueueSend, 17 | } 18 | 19 | use phoenix_common::engine::datapath::SendError; 20 | impl From> for DatapathError { 21 | fn from(_other: SendError) -> Self { 22 | DatapathError::InternalQueueSend 23 | } 24 | } 25 | 26 | use crate::config::QosConfig; 27 | use crate::module::QosAddon; 28 | 29 | #[no_mangle] 30 | pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { 31 | let config = QosConfig::new(config_string)?; 32 | let addon = QosAddon::new(config); 33 | Ok(Box::new(addon)) 34 | } 35 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/ratelimit/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-ratelimit" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | phoenix_common.workspace = true 10 | phoenix-api-policy-ratelimit.workspace = true 11 | 12 | futures.workspace = true 13 | minstant.workspace = true 14 | thiserror.workspace = true 15 | serde = { workspace = true, features = ["derive"] } 16 | serde_json.workspace = true 17 | anyhow.workspace = true 18 | nix.workspace = true 19 | toml = { workspace = true, features = ["preserve_order"] } 20 | bincode.workspace = true 21 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/ratelimit/src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Debug, Clone, Copy, Serialize, Deserialize)] 4 | #[serde(deny_unknown_fields)] 5 | pub struct RateLimitConfig { 6 | pub requests_per_sec: u64, 7 | pub bucket_size: u64, 8 | } 9 | 10 | impl Default for RateLimitConfig { 11 | fn default() -> Self { 12 | RateLimitConfig { 13 | requests_per_sec: 100000, 14 | bucket_size: 100000, 15 | } 16 | } 17 | } 18 | 19 | impl RateLimitConfig { 20 | pub fn new(config: Option<&str>) -> anyhow::Result { 21 | let config = toml::from_str(config.unwrap_or(""))?; 22 | Ok(config) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/policy/ratelimit/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(peer_credentials_unix_socket)] 2 | 3 | use thiserror::Error; 4 | 5 | pub use phoenix_common::{InitFnResult, PhoenixAddon}; 6 | 7 | pub mod config; 8 | pub(crate) mod engine; 9 | pub mod module; 10 | 11 | #[derive(Error, Debug)] 12 | pub(crate) enum DatapathError { 13 | #[error("Internal queue send error")] 14 | InternalQueueSend, 15 | } 16 | 17 | use phoenix_common::engine::datapath::SendError; 18 | impl From> for DatapathError { 19 | fn from(_other: SendError) -> Self { 20 | DatapathError::InternalQueueSend 21 | } 22 | } 23 | 24 | use crate::config::RateLimitConfig; 25 | use crate::module::RateLimitAddon; 26 | 27 | #[no_mangle] 28 | pub fn init_addon(config_string: Option<&str>) -> InitFnResult> { 29 | let config = RateLimitConfig::new(config_string)?; 30 | let addon = RateLimitAddon::new(config); 31 | Ok(Box::new(addon)) 32 | } 33 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/rpc_adapter/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-rpc-adapter" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | crate-type = ["rlib"] 10 | 11 | [dependencies] 12 | mrpc-marshal.workspace = true 13 | phoenix-api-mrpc.workspace = true 14 | phoenix-api-rpc-adapter.workspace = true 15 | phoenix-mrpc.workspace = true 16 | 17 | phoenix-api = { workspace = true, features = ["mrpc"] } 18 | ipc.workspace = true 19 | phoenix_common.workspace = true 20 | rdma = { workspace = true, features = ["phoenix"] } 21 | transport-rdma = { workspace = true, package = "phoenix-transport-rdma" } 22 | phoenix-salloc.workspace = true 23 | 24 | fnv.workspace = true 25 | anyhow.workspace = true 26 | tokio = { workspace = true, features = ["sync"] } 27 | thiserror.workspace = true 28 | nix.workspace = true 29 | futures.workspace = true 30 | dashmap.workspace = true 31 | spin.workspace = true 32 | libloading.workspace = true 33 | serde = { workspace = true, features = ["derive"] } 34 | toml = { workspace = true, features = ["preserve_order"] } 35 | fastrand.workspace = true 36 | bitvec.workspace = true 37 | bincode.workspace = true 38 | slab.workspace = true 39 | serde_json.workspace = true 40 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/rpc_adapter/src/acceptor/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod engine; 2 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/rpc_adapter/src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Debug, Clone, Serialize, Deserialize)] 4 | #[serde(deny_unknown_fields)] 5 | pub struct RpcAdapterConfig { 6 | pub enable_scheduler: bool, 7 | } 8 | 9 | impl RpcAdapterConfig { 10 | pub fn new(config: Option<&str>) -> anyhow::Result { 11 | let config = toml::from_str(config.unwrap_or(""))?; 12 | Ok(config) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/rpc_adapter/src/ulib/mod.rs: -------------------------------------------------------------------------------- 1 | use std::borrow::Borrow; 2 | use std::io; 3 | 4 | use thiserror::Error; 5 | 6 | use transport_rdma::ops::Ops; 7 | use transport_rdma::{ApiError, DatapathError}; 8 | 9 | #[allow(dead_code)] 10 | pub(crate) mod fp; 11 | 12 | #[allow(dead_code)] 13 | pub(crate) mod ucm; 14 | 15 | #[allow(dead_code)] 16 | pub(crate) mod uverbs; 17 | 18 | #[derive(Error, Debug)] 19 | pub(crate) enum Error { 20 | #[error("Error in RDMA API: {0}")] 21 | Api(#[from] ApiError), 22 | #[error("Datapath API Error: {0}")] 23 | Datapath(#[from] DatapathError), 24 | #[error("IO Error {0}")] 25 | Io(#[from] io::Error), 26 | #[error("No address is resolved")] 27 | NoAddrResolved, 28 | #[error("Connect failed: {0}")] 29 | Connect(ApiError), 30 | } 31 | 32 | // Get an owned structure from a borrow 33 | pub(crate) trait FromBorrow { 34 | fn from_borrow>(borrow: &T) -> Self; 35 | } 36 | 37 | #[inline] 38 | fn get_ops() -> &'static Ops { 39 | use super::engine::ELS; 40 | ELS.with(|els| &els.borrow().as_ref().unwrap().ops) 41 | } 42 | -------------------------------------------------------------------------------- /experimental/mrpc/plugin/tcp_rpc_adapter/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-tcp-rpc-adapter" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | crate-type = ["rlib"] 10 | 11 | [dependencies] 12 | phoenix-api-mrpc.workspace = true 13 | phoenix-api-tcp-rpc-adapter.workspace = true 14 | phoenix-mrpc.workspace = true 15 | mrpc-marshal.workspace = true 16 | 17 | phoenix-api = { workspace = true, features = ["mrpc", "transport"] } 18 | ipc.workspace = true 19 | phoenix_common.workspace = true 20 | transport-tcp.workspace = true 21 | phoenix-salloc.workspace = true 22 | utils.workspace = true 23 | 24 | fnv.workspace = true 25 | anyhow.workspace = true 26 | tokio = { workspace = true, features = ["sync"] } 27 | thiserror.workspace = true 28 | nix.workspace = true 29 | futures.workspace = true 30 | dashmap.workspace = true 31 | spin.workspace = true 32 | libloading.workspace = true 33 | serde = { workspace = true, features = ["derive"] } 34 | toml = { workspace = true, features = ["preserve_order"] } 35 | fastrand.workspace = true 36 | bitvec.workspace = true 37 | bincode.workspace = true 38 | socket2.workspace = true 39 | slab.workspace = true 40 | -------------------------------------------------------------------------------- /experimental/mrpc/rust-toolchain: -------------------------------------------------------------------------------- 1 | ../../rust-toolchain -------------------------------------------------------------------------------- /experimental/mrpc/src/stub/mod.rs: -------------------------------------------------------------------------------- 1 | //! Utilities used by the code generated by `mrpc-build`. 2 | use std::cell::RefCell; 3 | 4 | use crate::{Error, MRPC_CTX}; 5 | 6 | // Re-exports 7 | pub use phoenix_api::rpc::{MessageErased, MessageMeta, RpcMsgType}; 8 | pub use phoenix_api_mrpc::control_plane::TransportType; 9 | 10 | mod service; 11 | pub use service::{service_post_handler, service_pre_handler, NamedService, Service}; 12 | 13 | mod client; 14 | pub use client::{ClientStub, ReqFuture}; 15 | 16 | mod local_server; 17 | pub mod server; 18 | pub use local_server::LocalServer; 19 | 20 | pub(crate) mod conn; 21 | pub(crate) mod pending; 22 | pub(crate) mod reply_cache; 23 | 24 | // We can make RpcData a private trait, and only mark it for compiler generated types. 25 | // This seems impossible. 26 | /// Auto trait implmented for RPC request types that is safe to move to the writable shared memory heap. 27 | pub trait RpcData: Send + Sync + 'static {} 28 | impl RpcData for T {} 29 | 30 | // TODO(cjr): move this to mrpc::Context 31 | mod reactor; 32 | pub use reactor::Reactor; 33 | thread_local! { 34 | pub(crate) static LOCAL_REACTOR: RefCell = RefCell::new(Reactor::new()); 35 | } 36 | 37 | #[doc(hidden)] 38 | pub fn update_protos(protos: &[&str]) -> Result<(), Error> { 39 | MRPC_CTX.with(|ctx| ctx.update_protos(protos)) 40 | } 41 | -------------------------------------------------------------------------------- /experimental/mrpc/src/stub/pending.rs: -------------------------------------------------------------------------------- 1 | use std::cell::RefCell; 2 | 3 | use fnv::FnvHashMap as HashMap; 4 | 5 | use phoenix_api::rpc::RpcId; 6 | 7 | use super::RpcData; 8 | use crate::wref::{WRef, WRefOpaque}; 9 | 10 | /// A collection of pending (the RPC is on going) remote writable references. WRefs are added to 11 | /// this collection to prevent from being release while the backend still using them. 12 | #[derive(Debug, Default)] 13 | pub(crate) struct PendingWRef { 14 | // pool: DashMap, 15 | pool: RefCell>, 16 | } 17 | 18 | impl PendingWRef { 19 | #[inline] 20 | pub(crate) fn new() -> Self { 21 | Self::default() 22 | } 23 | 24 | #[inline] 25 | pub(crate) fn insert(&self, rpc_id: RpcId, wref: WRef) { 26 | self.insert_opaque(rpc_id, wref.into_opaque()) 27 | } 28 | 29 | #[inline] 30 | pub(crate) fn insert_opaque(&self, rpc_id: RpcId, wref_opaque: WRefOpaque) { 31 | self.pool.borrow_mut().insert(rpc_id, wref_opaque); 32 | } 33 | 34 | #[inline] 35 | pub(crate) fn remove(&self, rpc_id: &RpcId) { 36 | if self.pool.borrow_mut().remove(rpc_id).is_none() { 37 | panic!("PendingWRef::remove: rpc_id {:?} not found", rpc_id); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /experimental/mrpc/src/stub/server.rs: -------------------------------------------------------------------------------- 1 | //! [`Send`] and [`Sync`] Server implementation. 2 | -------------------------------------------------------------------------------- /mdbook/.gitignore: -------------------------------------------------------------------------------- 1 | book -------------------------------------------------------------------------------- /mdbook/README.md: -------------------------------------------------------------------------------- 1 | # Phoenix Documentation 2 | 3 | ## Quick Start 4 | 1. Install mdbook: 5 | ``` 6 | cargo install mdbook 7 | ``` 8 | 9 | 2. Work on your documentation while having an http server for it on 10 | localhost:3000, rebuilding on change. 11 | ``` 12 | mdbook serve 13 | ``` 14 | 15 | 3. Build the book and open a browser to view the result: 16 | ``` 17 | mdbook build -o 18 | ``` 19 | -------------------------------------------------------------------------------- /mdbook/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | title = "Phoenix Documentation" 3 | description = "Phoenix Documentation" 4 | authors = ["Yongji Wu", "Jingrong Chen"] 5 | language = "en" 6 | 7 | [rust] 8 | edition = "2021" 9 | 10 | [output.html] 11 | mathjax-support = true 12 | site-url = "/" 13 | git-repository-url = "https://github.com/phoenix-dataplane/phoenix/tree/main/mdbook" 14 | edit-url-template = "https://github.com/phoenix-dataplane/phoenix/edit/main/mdbook/{path}" 15 | 16 | [output.html.playground] 17 | editable = true 18 | line-numbers = true 19 | 20 | [output.html.search] 21 | limit-results = 20 22 | use-boolean-and = true 23 | boost-title = 2 24 | boost-hierarchy = 2 25 | boost-paragraph = 1 26 | expand = true 27 | heading-split-level = 2 28 | -------------------------------------------------------------------------------- /mdbook/src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [Introduction](introduction.md) 4 | - [mRPC Tutorials](tutorials/outline.md) 5 | - [Working with mRPC Library](tutorials/working-with-mrpc-library.md) 6 | - [Policy Management](tutorials/policy-management.md) 7 | -------------------------------------------------------------------------------- /mdbook/src/mrpc-ffi/cpp-ffi.md: -------------------------------------------------------------------------------- 1 | # mRPC C++ FFI 2 | -------------------------------------------------------------------------------- /mdbook/src/mrpc-ffi/outline.md: -------------------------------------------------------------------------------- 1 | # mRPC FFI 2 | -------------------------------------------------------------------------------- /mdbook/src/tutorials/outline.md: -------------------------------------------------------------------------------- 1 | # mRPC Tutorials 2 | This chapter covers tutorials of how to develop user applications with mRPC library, 3 | and how administers can manage applications and apply policies with the mRPC service. -------------------------------------------------------------------------------- /phoenix-logo-red-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phoenix-dataplane/phoenix/20495759ffebda10143d1b19bbb3b372ba7ef4a2/phoenix-logo-red-black.png -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2024-05-01" 3 | components = [ 4 | # development 5 | "cargo", "clippy", "rust-docs", "rust-std", "rustc", "rustfmt", "rust-analyzer", 6 | 7 | # for rust-analyzer to browser the code for rustc 8 | "rustc-dev", 9 | ] 10 | profile = "minimal" 11 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition = "2021" 2 | -------------------------------------------------------------------------------- /scripts/build_debug.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -euo pipefail 4 | 5 | main() { 6 | cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug -H. -Bbuild 7 | cmake --build build 8 | } 9 | 10 | main 11 | -------------------------------------------------------------------------------- /scripts/build_release.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -euo pipefail 4 | 5 | main() { 6 | cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -Bbuild 7 | cmake --build build 8 | } 9 | 10 | main 11 | -------------------------------------------------------------------------------- /scripts/check-git-clang-format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # compare against parent commit 4 | base_commit="HEAD^" 5 | echo "Running clang-format against parent commit $(git rev-parse "$base_commit")" 6 | 7 | if command -v git-clang-format; then 8 | git-clang-format --binary clang-format --commit "$base_commit" --diff 9 | fi 10 | -------------------------------------------------------------------------------- /scripts/clippy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find . | grep "\.rs$" | xargs touch ; cargo clippy 4 | -------------------------------------------------------------------------------- /scripts/config_eval.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cd ~/nfs/phoenix 3 | ssh danyang-05 "mkdir -p /tmp/lsh-phoenix; mkdir -p /tmp/mrpc-eval-tcp" 4 | ssh danyang-06 "mkdir -p /tmp/lsh-phoenix; mkdir -p /tmp/mrpc-eval-tcp" 5 | find . -name 'phoenix.toml' | xargs sed -i 's/\/tmp\/phoenix/\/tmp\/lsh-phoenix/g' 6 | find . -name 'config.toml' | xargs sed -i 's/PHOENIX_PREFIX = "\/tmp\/phoenix"/PHOENIX_PREFIX = "\/tmp\/lsh-phoenix"/g' 7 | 8 | -------------------------------------------------------------------------------- /scripts/count_loc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function info { 4 | echo "$(tput bold)$(tput setaf 10)"$*"$(tput sgr 0)" 5 | } 6 | 7 | 8 | info "miscellaneous code:" 9 | find src/experimental -type f -name "*.rs" | xargs wc -l 10 | info "3rdparty slabmalloc:" 11 | find src/slabmalloc -type f -name "*.rs" | xargs wc -l 12 | info "rdma bindings:" 13 | find src/rdma -type f -name "*.rs" | grep -v bindings | xargs wc -l 14 | info "phoenix examples:" 15 | find examples -type f -name "*.rs" | xargs wc -l 16 | 17 | info "phoenix total:" 18 | find src/ -type f -name "*.rs" | grep -v experimental | grep -v slabmalloc | grep -v bindings.rs | xargs wc -l 19 | info "phoenix doc/comments:" 20 | find src/ -type f -name "*.rs" | grep -v experimental | grep -v slabmalloc | grep -v bindings.rs | xargs grep -r '[[:space:]]*//' | wc -l 21 | 22 | info "3rdparty prost:" 23 | find experimental/mrpc/3rdparty/prost -type f -name "*.rs" | xargs wc -l 24 | info "mrpc examples:" 25 | find experimental/mrpc/examples -type f -name "*.rs" | xargs wc -l 26 | info "mrpc total:" 27 | find experimental/mrpc/ -type f -name "*.rs" | grep -v 3rdparty | grep -v examples | grep -v target | xargs wc -l 28 | info "phoenix doc/comments:" 29 | find experimental/mrpc/ -type f -name "*.rs" | grep -v 3rdparty | grep -v examples | grep -v target | xargs grep -r '[[:space:]]*//' | wc -l 30 | 31 | -------------------------------------------------------------------------------- /scripts/cpu_performance.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function usage() { 4 | echo "Usage: $0 [performance|powersave|ondemand]" 5 | exit 0 6 | } 7 | 8 | [[ -z "${1-}" ]] && usage "$0" 9 | case $1 in 10 | performance|powersave|ondemand) 11 | echo "Current scaling_governor:" 12 | cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 13 | echo "Switching to: $1" 14 | echo $1 | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor ;; 15 | *) usage "$0" ;; 16 | esac 17 | -------------------------------------------------------------------------------- /scripts/create_sysroot.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | WORKDIR=`dirname $(realpath $0)` 4 | TARGETDIR="${WORKDIR}"/../target 5 | SYSROOT_DIR="${TARGETDIR}"/sysroot 6 | 7 | 8 | cargo clean 9 | cargo build -r -p phoenix_common 10 | 11 | cp -r "${TARGETDIR}/release/deps" "${SYSROOT_DIR}" 12 | 13 | TOOLCHAIN_SYSROOT=`rustc --print sysroot` 14 | 15 | cp -r "${TOOLCHAIN_SYSROOT}/lib" "${SYSROOT_DIR}" 16 | -------------------------------------------------------------------------------- /scripts/deploy_plugins.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | PHOENIX_PREFIX="/tmp/phoenix" 3 | if [[ $# -ge 1 ]]; then 4 | PHOENIX_PREFIX=$1 5 | fi 6 | 7 | mkdir -p "${PHOENIX_PREFIX}/plugins" 8 | 9 | WORKDIR=`dirname $(realpath $0)` 10 | TARGETDIR="${WORKDIR}"/../target/phoenix 11 | 12 | if [[ $# -ge 2 ]]; then 13 | TARGETDIR=$2 14 | fi 15 | 16 | for plugin in `find "${TARGETDIR}"/release/ -maxdepth 1 -type f -name "libphoenix_*.rlib" -o -name "libphoenix_*.d"`; do 17 | install -v -Dm755 "${plugin}" -t "${PHOENIX_PREFIX}"/plugins/ 18 | done 19 | -------------------------------------------------------------------------------- /scripts/killall.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | pkill -9 mpstat 4 | pkill -9 rpc-bench 5 | pkill -9 envoy 6 | pkill -9 launcher 7 | pkill -9 phoenix 8 | ssh danyang-06 "pkill -9 mpstat; \ 9 | pkill -9 rpc-bench; \ 10 | pkill -9 envoy; \ 11 | pkill -9 launcher; \ 12 | pkill -9 phoenix" 13 | -------------------------------------------------------------------------------- /scripts/locate_symbol.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | for lib in `find target -type f -name "*.rlib"`; do 4 | echo $lib; 5 | # nm $lib | grep '_ZN86_$LT$libc..unix..linux_like..linux..gnu..b64..sigset_t$u20$as$u20$core..fmt..Debug$GT$3fmt17h43c84351e16aca3cE'; 6 | nm $lib | grep '__rust_probestack' --color 7 | done 8 | -------------------------------------------------------------------------------- /src/experimental/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | 3 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") 4 | 5 | # the executables 6 | add_executable(bench_lamport_spsc examples/bench_lamport_spsc.cc) 7 | target_link_libraries(bench_lamport_spsc pthread) 8 | 9 | add_executable(bench_lat examples/bench_lat.cc examples/get_clock.cc) 10 | target_link_libraries(bench_lat ibverbs rdmacm) 11 | 12 | add_executable(bench_bw examples/bench_bw.cc examples/get_clock.cc) 13 | target_link_libraries(bench_bw ibverbs rdmacm) 14 | -------------------------------------------------------------------------------- /src/experimental/examples/bench_bw.cc: -------------------------------------------------------------------------------- 1 | #include "bench_read_bw.h" 2 | #include "bench_send_bw.h" 3 | #include "bench_write_bw.h" 4 | 5 | int main(int argc, char **argv) 6 | { 7 | Context ctx; 8 | ctx.tst = BW; 9 | ctx.verb = SEND; 10 | ctx.num = 0, ctx.size = (1 << 16), ctx.client = false; 11 | 12 | parse(&ctx, argc, argv); 13 | int ret = set_params(&ctx); 14 | if (ret) 15 | goto out; 16 | 17 | printf("num: %u, size: %lu\n", ctx.num, ctx.size); 18 | 19 | switch (ctx.verb) 20 | { 21 | case SEND: 22 | printf("Send data from client to server\n"); 23 | if (ctx.client) 24 | ret = run_send_bw_client(&ctx); 25 | else 26 | ret = run_send_bw_server(&ctx); 27 | break; 28 | case WRITE: 29 | printf("Write data from client to server\n"); 30 | if (ctx.client) 31 | ret = run_write_bw_client(&ctx); 32 | else 33 | ret = run_write_bw_server(&ctx); 34 | break; 35 | case READ: 36 | printf("Read data from server to client\n"); 37 | if (ctx.client) 38 | ret = run_read_bw_client(&ctx); 39 | else 40 | ret = run_read_bw_server(&ctx); 41 | } 42 | 43 | free_ctx(&ctx); 44 | out: 45 | if (ret) 46 | printf("error %d\n", ret); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /src/experimental/examples/bench_timestamp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "get_clock.h" 12 | 13 | uint64_t Now64() 14 | { 15 | struct timespec tv; 16 | clock_gettime(CLOCK_REALTIME, &tv); 17 | return (uint64_t)tv.tv_sec * 1000000llu + (uint64_t)tv.tv_nsec; 18 | } 19 | 20 | int main() 21 | { 22 | int n = 10000000; 23 | uint64_t t; 24 | uint64_t start = Now64(); 25 | for (int i = 0; i < n; i++) 26 | t = get_cycles(); 27 | uint64_t finish = Now64(); 28 | uint64_t sum = finish - start; 29 | printf("%lu, %.2lf\n", sum, 1.0 * sum / n); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /src/experimental/examples/bench_timestamp.rs: -------------------------------------------------------------------------------- 1 | use std::thread::sleep; 2 | use std::time::{Duration, Instant}; 3 | 4 | fn main() { 5 | let n = 1000000; 6 | let start = Instant::now(); 7 | for i in 0..n { 8 | let now = Instant::now(); 9 | } 10 | let finish = Instant::now(); 11 | let sum = finish.duration_since(start).as_nanos() as f64; 12 | println!("{} {}", sum, 1.0 * sum / n as f64); 13 | } 14 | -------------------------------------------------------------------------------- /src/experimental/examples/socket_lat_receiver.rs: -------------------------------------------------------------------------------- 1 | use socket2::{Domain, Socket, Type}; 2 | use std::string::ToString; 3 | use std::{mem::MaybeUninit, net::SocketAddr}; 4 | 5 | fn main() -> Result<(), std::io::Error> { 6 | let listener = Socket::new(Domain::IPV4, Type::STREAM, None)?; 7 | let address: SocketAddr = "0.0.0.0:8080".parse().unwrap(); 8 | println!("Listening on {}", address.to_string()); 9 | listener.bind(&address.into())?; 10 | listener.listen(128)?; 11 | 12 | loop { 13 | let (socket, addr) = listener.accept()?; 14 | socket.set_nodelay(true)?; 15 | println!( 16 | "New connection from {}", 17 | addr.as_socket().unwrap().to_string() 18 | ); 19 | 20 | const LEN: usize = 128; 21 | let mut buf: [u8; LEN] = [0; LEN]; 22 | let buf = unsafe { &mut *(&mut buf[..] as *mut [u8] as *mut [MaybeUninit]) }; 23 | 24 | loop { 25 | if let Err(_e) = socket.recv(buf) { 26 | break; 27 | }; 28 | if let Err(_e) = socket.send(b"ack") { 29 | break; 30 | }; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/experimental/examples/test_dispatch_codegen.rs: -------------------------------------------------------------------------------- 1 | // use std::path::PathBuf; 2 | 3 | // use structopt::StructOpt; 4 | 5 | // use phoenix::mrpc::builder::build_serializer_lib; 6 | 7 | // const HELLO_PROTO: &'static str = include_str!("../proto/rpc_hello.proto"); 8 | // const DEFAULT_CACHE_DIR: &'static str = "/tmp/phoenix_dispatch"; 9 | 10 | // #[derive(StructOpt)] 11 | // struct Opt { 12 | // #[structopt(short = "p", parse(from_os_str))] 13 | // proto: Option, 14 | // #[structopt(short = "c", long = "cache", parse(from_os_str))] 15 | // cache_dir: Option, 16 | // } 17 | 18 | fn main() { 19 | // let opt = Opt::from_args(); 20 | // let proto = if let Some(path) = opt.proto { 21 | // std::fs::read_to_string(path).unwrap() 22 | // } else { 23 | // HELLO_PROTO.to_string() 24 | // }; 25 | // let protos = vec![proto]; 26 | // let cache_dir = opt.cache_dir.unwrap_or(DEFAULT_CACHE_DIR.into()); 27 | // build_serializer_lib(protos, cache_dir).unwrap(); 28 | } 29 | -------------------------------------------------------------------------------- /src/experimental/proto/rpc_hello.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015 gRPC authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package rpc_hello; 18 | 19 | // The greeting service definition. 20 | service Greeter { 21 | // Sends a greeting 22 | rpc SayHello (HelloRequest) returns (HelloReply) {} 23 | } 24 | 25 | // The request message containing the user's name. 26 | message HelloRequest { 27 | bytes name = 1; 28 | } 29 | 30 | // The response message containing the greetings 31 | message HelloReply { 32 | bytes message = 1; 33 | } 34 | -------------------------------------------------------------------------------- /src/experimental/src/aligned_alloc.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | use std::alloc::{AllocError, Allocator, Layout}; 3 | use std::ptr; 4 | use std::ptr::NonNull; 5 | 6 | struct AlignedAllocator; 7 | 8 | const PAGE_SIZE: usize = 4096; 9 | 10 | unsafe impl Allocator for AlignedAllocator { 11 | fn allocate(&self, layout: Layout) -> Result, std::alloc::AllocError> { 12 | let mut addr = ptr::null_mut(); 13 | let err = 14 | unsafe { libc::posix_memalign(&mut addr as *mut _ as _, PAGE_SIZE, layout.size()) }; 15 | if err != 0 { 16 | return Err(AllocError); 17 | } 18 | 19 | let ptr = NonNull::new(addr).unwrap(); 20 | Ok(NonNull::slice_from_raw_parts(ptr, layout.size())) 21 | } 22 | 23 | unsafe fn deallocate(&self, ptr: NonNull, _layout: Layout) { 24 | libc::free(ptr.as_ptr() as _); 25 | } 26 | } 27 | 28 | #[cfg(test)] 29 | mod tests { 30 | use super::*; 31 | #[test] 32 | fn test_usage() { 33 | let v: Vec = Vec::with_capacity_in(4096, AlignedAllocator); 34 | assert!((v.as_ptr() as usize) % PAGE_SIZE == 0); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/experimental/src/ipc_deprecated.rs: -------------------------------------------------------------------------------- 1 | use crate::ringbuffer::RingBuffer; 2 | use crate::shm::SharedMemory; 3 | use core::alloc::Allocator; 4 | 5 | pub enum IpcCommand { 6 | TestIpc, 7 | } 8 | 9 | pub enum IpcReply { 10 | TestIpc, 11 | } 12 | 13 | pub enum IpcError { 14 | ServerFailed, 15 | } 16 | 17 | pub type IpcResult = Result; 18 | 19 | struct SharedRegion(SharedMemory); 20 | 21 | pub struct QueuePair { 22 | wq: RingBuffer, 23 | cq: RingBuffer, A>, 24 | } 25 | 26 | pub struct IpcChannel { 27 | qp: Box, A>, 28 | shared_region: SharedRegion, 29 | alloc: A, 30 | } 31 | -------------------------------------------------------------------------------- /src/ipc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ipc" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | [dependencies] 8 | phoenix-api.workspace = true 9 | 10 | ipc-channel.workspace = true 11 | thiserror.workspace = true 12 | serde = { workspace = true, features = ["derive"] } 13 | bincode.workspace = true 14 | libc.workspace = true 15 | shmem-ipc.workspace = true 16 | zerocopy.workspace = true 17 | memfd.workspace = true 18 | memmap2.workspace = true 19 | uuid.workspace = true 20 | atomic-traits.workspace = true 21 | nix = { workspace = true, default-features = false, features = ["process"] } 22 | crossbeam.workspace = true 23 | unique.workspace = true 24 | minstant.workspace = true 25 | mio.workspace = true 26 | async-io = { workspace = true, optional = true } 27 | 28 | [features] 29 | customer = ["dep:async-io"] 30 | all = ["customer"] 31 | -------------------------------------------------------------------------------- /src/ipc/src/channel/flavors/concurrent.rs: -------------------------------------------------------------------------------- 1 | //! Concurrent channel, encapsulated over crossbeam channel. 2 | 3 | pub(crate) use crossbeam::channel::{unbounded, Receiver, Sender}; 4 | 5 | pub(crate) fn create_channel() -> (Sender, Receiver) { 6 | unbounded() 7 | } 8 | -------------------------------------------------------------------------------- /src/ipc/src/channel/flavors/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod concurrent; 2 | pub(crate) mod sequential; 3 | -------------------------------------------------------------------------------- /src/ipc/src/ipc_channel.rs: -------------------------------------------------------------------------------- 1 | //! Re-exports of some types in IPC-channel crate. 2 | //! It also provides an IpcSenderNotify class. 3 | use std::sync::atomic::{AtomicUsize, Ordering}; 4 | 5 | use serde::Serialize; 6 | 7 | use crate::shmobj::ShmObject; 8 | 9 | pub use ipc_channel::ipc::TryRecvError; 10 | pub(crate) use ipc_channel::ipc::{ 11 | channel, IpcError as IpcRecvError, IpcOneShotServer as OneShotServer, IpcReceiver, IpcSender, 12 | }; 13 | pub(crate) use ipc_channel::Error as IpcSendError; 14 | 15 | pub struct IpcSenderNotify { 16 | inner: IpcSender, 17 | entries: ShmObject, 18 | } 19 | 20 | impl IpcSenderNotify { 21 | pub(crate) fn new(inner: IpcSender, entries: ShmObject) -> Self { 22 | IpcSenderNotify { inner, entries } 23 | } 24 | 25 | pub(crate) fn send(&self, data: T) -> Result<(), bincode::Error> { 26 | self.inner.send(data)?; 27 | self.entries.fetch_add(1, Ordering::Relaxed); 28 | Ok(()) 29 | } 30 | } 31 | 32 | impl Clone for IpcSenderNotify 33 | where 34 | T: Serialize, 35 | { 36 | fn clone(&self) -> IpcSenderNotify { 37 | IpcSenderNotify { 38 | inner: self.inner.clone(), 39 | entries: self.entries.clone(), 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/ipc/src/shmem_ipc.rs: -------------------------------------------------------------------------------- 1 | //! Re-exports of shmem-ipc 2 | 3 | pub use shmem_ipc::ringbuf::Error as ShmRingbufError; 4 | pub use shmem_ipc::ringbuf::{Receiver as RingReceiver, Sender as RingSender}; 5 | 6 | pub use shmem_ipc::sharedring::{Receiver as ShmReceiver, Sender as ShmSender}; 7 | pub use shmem_ipc::Error as ShmIpcError; 8 | -------------------------------------------------------------------------------- /src/phoenix-common-workspace/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-common-workspace" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | # hack: these following features are manually enabled 10 | phoenix-api = { workspace = true, features = ["mrpc", "salloc", "transport"] } 11 | ipc = { workspace = true, features = ["all"] } 12 | 13 | futures-core = { workspace = true, features = ["default"] } 14 | crossbeam-utils = { version = "0.8.12", features = ["default"] } 15 | crossbeam-channel = { version = "0.5.9", features = ["default", "std", "crossbeam-utils"] } 16 | crossbeam-epoch = { version = "0.9.14", features = ["default"] } 17 | hashbrown = { version = "0.14.5", features = ["raw"] } 18 | mio = { workspace = true, features = ["default", "net", "os-ext", "os-poll"] } 19 | log = { workspace = true, features = ["std"] } 20 | once_cell = { version = "1.17.1", features = ["default", "unstable"] } 21 | getrandom = { version = "0.2.8", features = ["js", "rdrand", "std"] } 22 | ahash = { version = "0.7.6", features = ["default"] } 23 | tokio = { workspace = true, features = ["full"] } 24 | tracing-core = { workspace = true, features = ["default"] } 25 | semver = { version = "1.0.23", features = ["default", "std"] } 26 | -------------------------------------------------------------------------------- /src/phoenix-common-workspace/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub use ipc; 2 | pub use phoenix_api; 3 | 4 | pub use ahash; 5 | pub use crossbeam_channel; 6 | pub use crossbeam_epoch; 7 | pub use crossbeam_utils; 8 | pub use futures_core; 9 | pub use getrandom; 10 | pub use hashbrown; 11 | pub use log; 12 | pub use mio; 13 | pub use tokio; 14 | -------------------------------------------------------------------------------- /src/phoenix-syscalls/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-syscalls" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | # [lib] 8 | # crate-type = ["dylib", "rlib"] 9 | 10 | [dependencies] 11 | phoenix-api = { workspace = true, features = ["transport"] } 12 | ipc.workspace = true 13 | utils.workspace = true 14 | 15 | thiserror.workspace = true 16 | uuid.workspace = true 17 | libc.workspace = true 18 | fnv.workspace = true 19 | memfd.workspace = true 20 | memmap2.workspace = true 21 | spin.workspace = true 22 | lazy_static.workspace = true 23 | serde_json.workspace = true 24 | 25 | [features] 26 | -------------------------------------------------------------------------------- /src/phoenix_common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix_common" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | crate-type = ["rlib"] 10 | 11 | [dependencies] 12 | phoenix-common-workspace.workspace = true 13 | phoenix-api = { workspace = true, features = ["mrpc"] } # The feature mrpc should be removed in the future 14 | ipc.workspace = true 15 | 16 | # TODO: remove the dep to mrpc 17 | phoenix-api-mrpc = { path = "../../experimental/mrpc/phoenix-api/mrpc" } 18 | 19 | tracing.workspace = true 20 | anyhow.workspace = true 21 | thiserror.workspace = true 22 | crossbeam.workspace = true 23 | nix = { workspace = true, default-features = false, features = ["signal", "process"] } 24 | fnv.workspace = true 25 | futures = { workspace = true, features = ["executor", "thread-pool"] } 26 | tokio = { workspace = true, features = ["sync"] } 27 | dashmap.workspace = true 28 | static_assertions.workspace = true 29 | semver.workspace = true 30 | sharded-slab.workspace = true 31 | libnuma.workspace = true 32 | libnuma-sys.workspace = true 33 | -------------------------------------------------------------------------------- /src/phoenix_common/src/engine/datapath/message.rs: -------------------------------------------------------------------------------- 1 | use std::ptr::Unique; 2 | 3 | use phoenix_api::rpc::{CallId, MessageMeta, RpcId, TransportStatus}; 4 | use phoenix_api::Handle; 5 | use phoenix_api_mrpc::dp::RECV_RECLAIM_BS; 6 | 7 | // use crate::mrpc::meta_pool::MetaBufferPtr; 8 | use super::meta_pool::MetaBufferPtr; 9 | 10 | // TODO(cjr): Should be repr(C) 11 | 12 | #[derive(Debug)] 13 | pub struct RpcMessageTx { 14 | // Each RPC message is assigned a buffer for meta and optionally for its data 15 | pub meta_buf_ptr: MetaBufferPtr, 16 | pub addr_backend: usize, 17 | } 18 | 19 | #[derive(Debug)] 20 | pub enum EngineTxMessage { 21 | RpcMessage(RpcMessageTx), 22 | ReclaimRecvBuf(Handle, [CallId; RECV_RECLAIM_BS]), 23 | } 24 | 25 | #[derive(Debug)] 26 | pub struct RpcMessageRx { 27 | pub meta: Unique, 28 | pub addr_app: usize, 29 | pub addr_backend: usize, 30 | } 31 | 32 | #[derive(Debug)] 33 | pub enum EngineRxMessage { 34 | RpcMessage(RpcMessageRx), 35 | Ack(RpcId, TransportStatus), 36 | // (conn_id, status), we cannot know which rpc_id the receive corresponds 37 | RecvError(Handle, TransportStatus), 38 | } 39 | -------------------------------------------------------------------------------- /src/phoenix_common/src/engine/datapath/mod.rs: -------------------------------------------------------------------------------- 1 | pub use channel::{create_channel, ChannelFlavor, SendError, TryRecvError}; 2 | pub use ipc::channel; 3 | 4 | pub mod message; 5 | pub mod node; 6 | 7 | pub use message::{EngineRxMessage, EngineTxMessage, RpcMessageRx, RpcMessageTx}; 8 | pub use node::DataPathNode; 9 | pub use node::{ChannelDescriptor, RxIQueue, RxOQueue, TxIQueue, TxOQueue, Vertex}; 10 | 11 | #[allow(clippy::len_without_is_empty)] 12 | pub mod meta_pool; 13 | -------------------------------------------------------------------------------- /src/phoenix_common/src/engine/decompose.rs: -------------------------------------------------------------------------------- 1 | use super::datapath::node::DataPathNode; 2 | use crate::storage::{ResourceCollection, SharedStorage}; 3 | 4 | pub type DecomposeResult = anyhow::Result; 5 | 6 | pub trait Decompose { 7 | /// Perform preparatory work before decompose the engine, 8 | /// e.g., flush data and command queues 9 | fn flush(&mut self) -> DecomposeResult; 10 | 11 | /// Decompose the engines to compositional states, 12 | /// and extract the data path node 13 | fn decompose( 14 | self: Box, 15 | shared: &mut SharedStorage, 16 | global: &mut ResourceCollection, 17 | ) -> (ResourceCollection, DataPathNode); 18 | } 19 | -------------------------------------------------------------------------------- /src/phoenix_common/src/engine/future.rs: -------------------------------------------------------------------------------- 1 | use std::future::Future; 2 | use std::pin::Pin; 3 | use std::task::{Context, Poll}; 4 | 5 | pub async fn yield_now() { 6 | /// Yield implementation 7 | struct YieldNow { 8 | yielded: bool, 9 | } 10 | 11 | impl Future for YieldNow { 12 | type Output = (); 13 | 14 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { 15 | if self.yielded { 16 | return Poll::Ready(()); 17 | } 18 | 19 | self.yielded = true; 20 | cx.waker().wake_by_ref(); 21 | Poll::Pending 22 | } 23 | } 24 | 25 | YieldNow { yielded: false }.await 26 | } 27 | -------------------------------------------------------------------------------- /src/phoenix_common/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(peer_credentials_unix_socket)] 2 | #![feature(ptr_internals)] 3 | 4 | pub extern crate tracing; 5 | // alias 6 | pub extern crate tracing as log; 7 | 8 | #[allow(clippy::missing_safety_doc)] 9 | pub mod addon; 10 | #[allow(clippy::missing_safety_doc)] 11 | pub mod module; 12 | 13 | pub mod engine; 14 | #[allow(clippy::missing_safety_doc)] 15 | pub mod envelop; 16 | pub mod local_resource; 17 | 18 | pub mod page_padded; 19 | pub mod resource; 20 | pub mod state_mgr; 21 | pub mod storage; 22 | 23 | pub type PhoenixResult = anyhow::Result; 24 | 25 | // Re-export for plugin implementer's use 26 | pub type InitFnResult = anyhow::Result; 27 | pub use addon::PhoenixAddon; 28 | pub use module::PhoenixModule; 29 | 30 | // Takes an optional configuration string. 31 | pub type InitAddonFn = fn(Option<&str>) -> InitFnResult>; 32 | pub type InitModuleFn = fn(Option<&str>) -> InitFnResult>; 33 | -------------------------------------------------------------------------------- /src/phoenix_common/src/page_padded.rs: -------------------------------------------------------------------------------- 1 | #[repr(align(4096))] 2 | pub struct PagePadded(T); 3 | 4 | unsafe impl Send for PagePadded {} 5 | unsafe impl Sync for PagePadded {} 6 | 7 | impl PagePadded { 8 | pub const fn new(t: T) -> PagePadded { 9 | PagePadded::(t) 10 | } 11 | 12 | pub fn into_inner(self) -> T { 13 | self.0 14 | } 15 | } 16 | 17 | use std::ops::{Deref, DerefMut}; 18 | impl Deref for PagePadded { 19 | type Target = T; 20 | 21 | fn deref(&self) -> &T { 22 | &self.0 23 | } 24 | } 25 | 26 | impl DerefMut for PagePadded { 27 | fn deref_mut(&mut self) -> &mut T { 28 | &mut self.0 29 | } 30 | } 31 | 32 | use std::fmt; 33 | impl fmt::Debug for PagePadded { 34 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 35 | f.debug_struct("PagePadded") 36 | .field("value", &self.0) 37 | .finish() 38 | } 39 | } 40 | 41 | impl From for PagePadded { 42 | fn from(t: T) -> Self { 43 | PagePadded::new(t) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/phoenixctl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenixctl" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | ipc.workspace = true 10 | phoenix-api.workspace = true 11 | 12 | phoenix-api-policy-ratelimit = { path = "../../experimental/mrpc/phoenix-api/policy/ratelimit" } 13 | phoenix-api-policy-qos = { path = "../../experimental/mrpc/phoenix-api/policy/qos" } 14 | phoenix-api-rpc-adapter = { path = "../../experimental/mrpc/phoenix-api/rpc_adapter" } 15 | 16 | uuid.workspace = true 17 | bincode.workspace = true 18 | clap = { workspace = true, features = ["derive"] } 19 | serde = { workspace = true, features = ["derive"] } 20 | serde_json.workspace = true 21 | toml = { workspace = true, features = ["preserve_order"] } 22 | lazy_static.workspace = true 23 | prettytable-rs.workspace = true 24 | -------------------------------------------------------------------------------- /src/phoenixos/src/runtime/lb.rs: -------------------------------------------------------------------------------- 1 | //! Engine load balancer assigns engines to runtimes. 2 | 3 | use phoenix_common::engine::Engine; 4 | 5 | pub(crate) trait EngineBalancer { 6 | /// Schedule a runtime for this engine. 7 | fn submit(&self, engine: E); 8 | } 9 | -------------------------------------------------------------------------------- /src/phoenixos/src/runtime/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod container; 2 | pub(crate) use container::EngineContainer; 3 | 4 | pub(crate) mod executor; 5 | 6 | pub(crate) mod manager; 7 | pub(crate) use manager::RuntimeManager; 8 | 9 | pub(crate) mod group; 10 | pub(crate) use group::SchedulingGroup; 11 | 12 | pub(crate) mod graph; 13 | 14 | pub(crate) mod upgrade; 15 | pub(crate) use upgrade::EngineUpgrader; 16 | 17 | pub(crate) mod affinity; 18 | 19 | pub(crate) mod lb; 20 | -------------------------------------------------------------------------------- /src/plugin/salloc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-salloc" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | crate-type = ["rlib"] 10 | 11 | [dependencies] 12 | phoenix-api = { workspace = true, features = ["salloc"] } 13 | ipc.workspace = true 14 | mmap.workspace = true 15 | phoenix_common.workspace = true 16 | 17 | anyhow.workspace = true 18 | nix.workspace = true 19 | uuid.workspace = true 20 | memfd.workspace = true 21 | thiserror.workspace = true 22 | spin.workspace = true 23 | libc.workspace = true 24 | futures.workspace = true # unused futures 25 | serde = { workspace = true, features = ["derive"] } 26 | toml = { workspace = true, features = ["preserve_order"] } 27 | -------------------------------------------------------------------------------- /src/plugin/salloc/src/config.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use serde::{Deserialize, Serialize}; 4 | 5 | #[derive(Debug, Clone, Serialize, Deserialize)] 6 | #[serde(default, deny_unknown_fields)] 7 | pub struct SallocConfig { 8 | pub prefix: Option, 9 | pub engine_basename: String, 10 | } 11 | 12 | impl SallocConfig { 13 | pub fn new(config: Option<&str>) -> anyhow::Result { 14 | let config = toml::from_str(config.unwrap_or(""))?; 15 | Ok(config) 16 | } 17 | } 18 | 19 | impl Default for SallocConfig { 20 | fn default() -> Self { 21 | SallocConfig { 22 | prefix: None, 23 | engine_basename: "salloc-engine".to_owned(), 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/plugin/scheduler/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod engine; 2 | pub mod module; 3 | mod stacked_buffer; 4 | 5 | // pub use crate::module::PhoenixModule; 6 | // pub use crate::plugin::InitFnResult; 7 | -------------------------------------------------------------------------------- /src/plugin/scheduler/stacked_buffer.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | use std::mem::MaybeUninit; 3 | 4 | /// A zero-cost buffer allocated on the stack. 5 | /// Safety: users should manually care the safety, including uninitialized memory and boundary. 6 | #[allow(unused)] 7 | pub(crate) struct StackedBuffer { 8 | buf: [MaybeUninit; COUNT], 9 | len: usize, 10 | } 11 | 12 | impl StackedBuffer { 13 | pub(crate) fn new() -> Self { 14 | StackedBuffer { 15 | buf: unsafe { MaybeUninit::uninit().assume_init() }, 16 | len: 0, 17 | } 18 | } 19 | 20 | #[inline(always)] 21 | pub(crate) fn len(&self) -> usize { 22 | self.len 23 | } 24 | 25 | #[inline(always)] 26 | pub(crate) fn append(&mut self, val: T) { 27 | self.buf[self.len].write(val); 28 | self.len += 1; 29 | } 30 | 31 | #[inline(always)] 32 | pub(crate) fn as_slice(&self) -> &[T] { 33 | unsafe { mem::transmute::<_, &[T]>(&self.buf[0..self.len]) } 34 | } 35 | 36 | #[inline(always)] 37 | #[allow(unused)] 38 | pub(crate) unsafe fn get_unchecked(&self, idx: usize) -> &T { 39 | mem::transmute::<_, &T>(&self.buf[idx]) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/plugin/transport-rdma/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-transport-rdma" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | crate-type = ["rlib"] 10 | 11 | [dependencies] 12 | phoenix-api = { workspace = true, features = ["transport"] } 13 | ipc.workspace = true 14 | rdma = { workspace = true, features = ["phoenix"] } 15 | phoenix_common.workspace = true 16 | 17 | tokio = { workspace = true, features = ["sync"] } 18 | anyhow.workspace = true 19 | lazy_static.workspace = true 20 | nix.workspace = true 21 | uuid.workspace = true 22 | thiserror.workspace = true 23 | spin.workspace = true 24 | fnv.workspace = true 25 | mio = { version = "0.7.13", features = ["os-poll", "os-ext"] } 26 | futures.workspace = true # Please prune the unused features 27 | memoffset.workspace = true 28 | serde = { workspace = true, features = ["derive"] } 29 | toml = { workspace = true, features = ["preserve_order"] } 30 | serde_json.workspace = true 31 | -------------------------------------------------------------------------------- /src/plugin/transport-rdma/src/config.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use serde::{Deserialize, Serialize}; 4 | 5 | #[derive(Debug, Clone, Serialize, Deserialize)] 6 | #[serde(default, deny_unknown_fields)] 7 | pub struct RdmaTransportConfig { 8 | pub prefix: Option, 9 | pub engine_basename: String, 10 | pub datapath_wq_depth: usize, 11 | pub datapath_cq_depth: usize, 12 | pub command_max_interval_ms: u32, 13 | } 14 | 15 | impl Default for RdmaTransportConfig { 16 | fn default() -> Self { 17 | RdmaTransportConfig { 18 | prefix: None, 19 | engine_basename: String::from("transport-engine-rdma"), 20 | datapath_wq_depth: 32, 21 | datapath_cq_depth: 32, 22 | command_max_interval_ms: 1000, 23 | } 24 | } 25 | } 26 | 27 | impl RdmaTransportConfig { 28 | pub fn new(config: Option<&str>) -> anyhow::Result { 29 | let config = toml::from_str(config.unwrap_or(""))?; 30 | Ok(config) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/plugin/transport-tcp/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix-transport-tcp" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | crate-type = ["rlib"] 10 | 11 | [dependencies] 12 | phoenix-api.workspace = true 13 | ipc.workspace = true 14 | phoenix_common.workspace = true 15 | 16 | tokio = { workspace = true, features = ["sync"] } 17 | anyhow.workspace = true 18 | lazy_static.workspace = true 19 | nix.workspace = true 20 | uuid.workspace = true 21 | thiserror.workspace = true 22 | spin.workspace = true 23 | fnv.workspace = true 24 | mio = { workspace = true, features = ["os-poll", "net"] } 25 | futures.workspace = true 26 | memoffset.workspace = true 27 | socket2.workspace = true 28 | serde = { workspace = true, features = ["derive"] } 29 | toml = { workspace = true, features = ["preserve_order"] } 30 | -------------------------------------------------------------------------------- /src/plugin/transport-tcp/src/config.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use serde::{Deserialize, Serialize}; 4 | 5 | #[derive(Debug, Clone, Serialize, Deserialize)] 6 | #[serde(default, deny_unknown_fields)] 7 | pub struct TcpTransportConfig { 8 | pub prefix: Option, 9 | pub engine_basename: String, 10 | } 11 | 12 | impl Default for TcpTransportConfig { 13 | fn default() -> Self { 14 | TcpTransportConfig { 15 | prefix: None, 16 | engine_basename: String::from("transport-engine-tcp"), 17 | } 18 | } 19 | } 20 | 21 | impl TcpTransportConfig { 22 | pub fn new(config: Option<&str>) -> anyhow::Result { 23 | let config = toml::from_str(config.unwrap_or(""))?; 24 | Ok(config) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/shm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "shm" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | mmap.workspace = true 10 | 11 | nix.workspace = true 12 | lazy_static.workspace = true 13 | smol.workspace = true 14 | memfd.workspace = true 15 | spin.workspace = true 16 | thiserror.workspace = true 17 | 18 | [features] 19 | mrpc = [] 20 | -------------------------------------------------------------------------------- /src/shm/shmalloc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "shmalloc" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | [dependencies] 8 | mmap.workspace = true 9 | slabmalloc.workspace = true 10 | phoenix-syscalls.workspace = true 11 | phoenix-api = { workspace = true, features = ["salloc"] } 12 | ipc.workspace = true 13 | shm.workspace = true 14 | 15 | lazy_static.workspace = true 16 | smol.workspace = true 17 | memfd.workspace = true 18 | spin.workspace = true 19 | thiserror.workspace = true 20 | -------------------------------------------------------------------------------- /src/shm/shmalloc/README.md: -------------------------------------------------------------------------------- 1 | This crate is similar to malloc in libc. It maintains the heap with slab 2 | allocation algorithm and communicates with the backend plugin to 3 | acquire/release shared memory. 4 | -------------------------------------------------------------------------------- /src/shm/shmalloc/src/backend.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | use thiserror::Error; 4 | 5 | use ipc::service::ShmService; 6 | use phoenix_api::engine::SchedulingHint; 7 | use phoenix_api::salloc::{cmd, dp}; 8 | 9 | use phoenix_syscalls::{PHOENIX_CONTROL_SOCK, PHOENIX_PREFIX}; 10 | 11 | thread_local! { 12 | /// Initialization is dynamically performed on the first call to with within a thread. 13 | #[doc(hidden)] 14 | pub static SA_CTX: SAContext = SAContext::register().expect("phoenix salloc register failed"); 15 | } 16 | 17 | pub struct SAContext { 18 | pub(crate) service: 19 | ShmService, 20 | } 21 | 22 | impl SAContext { 23 | fn register() -> Result { 24 | let service = ShmService::register( 25 | &*PHOENIX_PREFIX, 26 | &*PHOENIX_CONTROL_SOCK, 27 | "Salloc".to_string(), 28 | SchedulingHint::default(), 29 | None, 30 | )?; 31 | Ok(Self { service }) 32 | } 33 | } 34 | 35 | #[derive(Error, Debug)] 36 | pub enum Error { 37 | #[error("Service error: {0}")] 38 | Service(#[from] ipc::Error), 39 | #[error("IO Error {0}")] 40 | Io(#[from] io::Error), 41 | #[error("Interface error {0}: {1}")] 42 | Interface(&'static str, phoenix_api::Error), 43 | } 44 | -------------------------------------------------------------------------------- /src/shm/shmalloc/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(allocator_api)] 2 | #![feature(strict_provenance)] 3 | 4 | pub mod wheap; 5 | pub use wheap::SharedHeapAllocator; 6 | 7 | pub mod backend; 8 | pub(crate) mod gc; 9 | -------------------------------------------------------------------------------- /src/shm/src/collections/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/shm/src/ptr/mod.rs: -------------------------------------------------------------------------------- 1 | //! Shared memory pointer types. 2 | 3 | pub mod shm_non_null; 4 | pub use shm_non_null::ShmNonNull; 5 | 6 | pub mod shmptr; 7 | pub use shmptr::ShmPtr; 8 | -------------------------------------------------------------------------------- /src/slabmalloc/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # See 2 | # https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/enabling-and-disabling-version-updates 3 | # for details 4 | 5 | version: 2 6 | updates: 7 | # Enable crate version updates for the main crate 8 | - package-ecosystem: "cargo" 9 | # Look `Cargo.toml` in the repository root 10 | directory: "/" 11 | # Check for updates every day (weekdays) 12 | schedule: 13 | interval: "daily" -------------------------------------------------------------------------------- /src/slabmalloc/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled files 2 | *.o 3 | *.so 4 | *.rlib 5 | *.dll 6 | 7 | # Executables 8 | *.exe 9 | 10 | # Generated by Cargo 11 | /target/ 12 | Cargo.lock 13 | *.log -------------------------------------------------------------------------------- /src/slabmalloc/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: nightly -------------------------------------------------------------------------------- /src/slabmalloc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "slabmalloc" 3 | version = "0.10.0" 4 | authors = ["Gerd Zellweger "] 5 | description = "Simple slab based malloc implementation in rust. Can be used stand-alone or in order to provide the necessary interface to rusts liballoc library. slabmalloc only relies on libcore." 6 | homepage = "https://github.com/gz/rust-slabmalloc" 7 | repository = "https://github.com/gz/rust-slabmalloc" 8 | documentation = "https://docs.rs/slabmalloc" 9 | readme = "README.md" 10 | license = "MIT" 11 | edition = "2018" 12 | 13 | keywords = ["os", "malloc", "slab", "alloc", "memory"] 14 | 15 | [features] 16 | unstable = [] 17 | default = [ "unstable" ] 18 | 19 | [dependencies] 20 | log = "0.4" 21 | arrayvec = { version = "0.7", default-features = false } 22 | spin = "0.9.3" 23 | lazy_static = "1.4.0" 24 | 25 | [target.'cfg(unix)'.dev-dependencies] 26 | rand = "0.8" 27 | env_logger = "0.9" 28 | -------------------------------------------------------------------------------- /src/slabmalloc/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Gerd Zellweger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /src/utils/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "utils" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | minstant.workspace = true 10 | smallvec.workspace = true 11 | -------------------------------------------------------------------------------- /src/utils/src/bounded_vec.rs: -------------------------------------------------------------------------------- 1 | use std::collections::VecDeque; 2 | use std::ops::{Deref, DerefMut}; 3 | 4 | #[derive(Debug, Clone, PartialEq, Eq)] 5 | pub struct BoundedVecDeque { 6 | queue: VecDeque, 7 | max_bound: usize, 8 | } 9 | 10 | impl BoundedVecDeque { 11 | pub fn new() -> Self { 12 | BoundedVecDeque { 13 | queue: VecDeque::new(), 14 | max_bound: 0, 15 | } 16 | } 17 | 18 | pub fn set_bound(&mut self, max_bound: usize) { 19 | self.max_bound = max_bound; 20 | } 21 | 22 | pub fn push_back_checked(&mut self, val: T) -> Result<(), T> { 23 | if self.queue.len() < self.max_bound { 24 | self.queue.push_back(val); 25 | Ok(()) 26 | } else { 27 | Err(val) 28 | } 29 | } 30 | } 31 | 32 | impl Default for BoundedVecDeque { 33 | fn default() -> Self { 34 | Self::new() 35 | } 36 | } 37 | 38 | impl Deref for BoundedVecDeque { 39 | type Target = VecDeque; 40 | fn deref(&self) -> &Self::Target { 41 | &self.queue 42 | } 43 | } 44 | 45 | impl DerefMut for BoundedVecDeque { 46 | fn deref_mut(&mut self) -> &mut Self::Target { 47 | &mut self.queue 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/utils/src/cmd_helper.rs: -------------------------------------------------------------------------------- 1 | use std::process::Command; 2 | 3 | pub fn get_command_str(cmd: &Command) -> String { 4 | let prog = cmd.get_program().to_str().unwrap(); 5 | let args: Vec<&str> = cmd.get_args().map(|x| x.to_str().unwrap()).collect(); 6 | std::iter::once(prog) 7 | .chain(args) 8 | .collect::>() 9 | .join(" ") 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod bounded_vec; 2 | pub mod cmd_helper; 3 | 4 | pub mod timer; 5 | -------------------------------------------------------------------------------- /src/utils/src/timer.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use std::time::Duration; 3 | 4 | use minstant::Instant; 5 | use smallvec::SmallVec; 6 | 7 | #[derive(Debug, Clone)] 8 | pub struct Timer { 9 | start: Instant, 10 | durations: SmallVec<[Duration; 8]>, 11 | } 12 | 13 | impl Timer { 14 | #[inline] 15 | pub fn new() -> Self { 16 | Self { 17 | start: Instant::now(), 18 | durations: Default::default(), 19 | } 20 | } 21 | 22 | #[inline] 23 | pub fn tick(&mut self) { 24 | self.durations.push(self.start.elapsed()); 25 | } 26 | } 27 | 28 | impl Default for Timer { 29 | fn default() -> Self { 30 | Timer::new() 31 | } 32 | } 33 | 34 | impl fmt::Display for Timer { 35 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 36 | f.debug_struct("Timer") 37 | .field("duras", &self.durations) 38 | .finish() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tools/phoenix_cargo/.gitignore: -------------------------------------------------------------------------------- 1 | # Build directories 2 | target/ 3 | bin/ 4 | .crates* 5 | -------------------------------------------------------------------------------- /tools/phoenix_cargo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "phoenix_cargo" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.1.6", features = ["derive"] } 10 | anyhow.workspace = true 11 | getopts = "0.2.21" 12 | regex = "1.7.1" 13 | toml.workspace = true 14 | serde = { workspace = true, features = ["derive"] } 15 | walkdir = "2.3.2" 16 | shlex = "1.1.0" 17 | semver.workspace = true 18 | rayon = "1.7.0" 19 | ansi_term.workspace = true 20 | --------------------------------------------------------------------------------