Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CP-52708: Avoid making Unix read/write calls for internal API calls: … #6178

Draft
wants to merge 1 commit into
base: feature/perf
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions ocaml/xapi/helpers.ml
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,11 @@ module TraceHelper = struct
Tracing_propagator.Propagator.Http.inject_into trace_context
end

(** Once the server functor has been instantiated, xapi sets this reference to the appropriate
"fake_rpc" (loopback non-HTTP) rpc function.
This way, internally the coordinator can short-circuit API calls without having to go over the network. *)
let rpc_fun : (Http.Request.t -> Rpc.call -> Rpc.response) option ref = ref None

(* Note that both this and `make_timeboxed_rpc` are almost always
* partially applied, returning a function of type 'Rpc.request -> Rpc.response'.
* The body is therefore not evaluated until the RPC call is actually being
Expand All @@ -418,18 +423,22 @@ let make_rpc ~__context rpc : Rpc.response =
in
let http = xmlrpc ~subtask_of ~version:"1.1" path in
let http = TraceHelper.inject_span_into_req tracing http in
let transport =
if Pool_role.is_master () then
Unix Xapi_globs.unix_domain_socket
else
SSL
( SSL.make ~use_stunnel_cache:true ~verify_cert:(Stunnel_client.pool ())
()
, Pool_role.get_master_address ()
, !Constants.https_port
)
in
dorpc ~srcstr:"xapi" ~dststr:"xapi" ~transport ~http rpc
match !rpc_fun with
| Some rpcfun when Pool_role.is_master () ->
rpcfun http rpc
| _ ->
let transport =
if Pool_role.is_master () then
Unix Xapi_globs.unix_domain_socket
else
SSL
( SSL.make ~use_stunnel_cache:true
~verify_cert:(Stunnel_client.pool ()) ()
, Pool_role.get_master_address ()
, !Constants.https_port
)
in
dorpc ~srcstr:"xapi" ~dststr:"xapi" ~transport ~http rpc

let make_timeboxed_rpc ~__context timeout rpc : Rpc.response =
let subtask_of = Ref.string_of (Context.get_task_id __context) in
Expand Down
7 changes: 7 additions & 0 deletions ocaml/xapi/xapi.ml
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,18 @@ let random_setup () =
finally (fun () -> really_input chan s 0 n) (fun () -> close_in chan) ;
Random.full_init (Array.init n (fun i -> Char.code (Bytes.get s i)))

let dummy_fd, dummy_fd2 = Unix.pipe ()

let () = Unix.close dummy_fd

let fake_rpc2 req rpc = Api_server.Server.dispatch_call req dummy_fd2 rpc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes dummy_fd2 slot into the origin type of ocaml/xapi/context.ml, which needs to be handled by all of its user, like the preauth, _client_of_origin, parent_of_origin, and others.

This needs a closer look, I doubt it can work as-is


let register_callback_fns () =
let fake_rpc req sock xml : Rpc.response =
Api_server.callback1 false req sock xml
in
Xapi_cli.rpc_fun := Some fake_rpc ;
Helpers.rpc_fun := Some fake_rpc2 ;
Message_forwarding.register_callback_fns ()

let noevents = ref false
Expand Down
Loading