From dc16d32cd97484ef7472a1aadf04c0fafa90f66c Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Fri, 8 Jan 2021 15:04:11 +0500 Subject: [PATCH 01/17] use _intf design pattern to dedup module types from 'smart_git.ml/mli' --- src/not-so-smart/dune | 2 +- src/not-so-smart/smart_git.ml | 49 +----------- src/not-so-smart/smart_git.mli | 112 +--------------------------- src/not-so-smart/smart_git_intf.ml | 116 +++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+), 159 deletions(-) create mode 100644 src/not-so-smart/smart_git_intf.ml diff --git a/src/not-so-smart/dune b/src/not-so-smart/dune index 7f8080165..d73fafd8a 100644 --- a/src/not-so-smart/dune +++ b/src/not-so-smart/dune @@ -51,7 +51,7 @@ (library (name smart_git) (public_name git.nss.git) - (modules smart_git) + (modules smart_git smart_git_intf) (libraries mimic mirage-flow unixiz ipaddr decompress.de decompress.zl cstruct logs astring result rresult bigstringaf fmt emile lwt domain-name uri sigs smart pck nss digestif carton carton-lwt)) diff --git a/src/not-so-smart/smart_git.ml b/src/not-so-smart/smart_git.ml index 17362a2dd..3bdfb290c 100644 --- a/src/not-so-smart/smart_git.ml +++ b/src/not-so-smart/smart_git.ml @@ -1,32 +1,4 @@ -module type APPEND = sig - type 'a rd = < rd : unit ; .. > as 'a - type 'a wr = < wr : unit ; .. > as 'a - - type 'a mode = - | Rd : < rd : unit > mode - | Wr : < wr : unit > mode - | RdWr : < rd : unit ; wr : unit > mode - - type t - type uid - type 'a fd - type error - type +'a fiber - - val pp_error : error Fmt.t - val create : mode:'a mode -> t -> uid -> ('a fd, error) result fiber - val map : t -> 'm rd fd -> pos:int64 -> int -> Bigstringaf.t fiber - val append : t -> 'm wr fd -> string -> unit fiber - val move : t -> src:uid -> dst:uid -> (unit, error) result fiber - val close : t -> 'm fd -> (unit, error) result fiber -end - -module type UID = sig - include Carton.UID - include Sigs.UID with type t := t - - val hash : t -> int -end +include Smart_git_intf module Verbose = struct type 'a fiber = 'a Lwt.t @@ -35,25 +7,6 @@ module Verbose = struct let print () = Lwt.return_unit end -module type HTTP = sig - type error - - val pp_error : error Fmt.t - - val get : - ctx:Mimic.ctx -> - ?headers:(string * string) list -> - Uri.t -> - (unit * string, error) result Lwt.t - - val post : - ctx:Mimic.ctx -> - ?headers:(string * string) list -> - Uri.t -> - string -> - (unit * string, error) result Lwt.t -end - let ( <.> ) f g x = f (g x) module Endpoint = struct diff --git a/src/not-so-smart/smart_git.mli b/src/not-so-smart/smart_git.mli index 66fb5652a..68c330710 100644 --- a/src/not-so-smart/smart_git.mli +++ b/src/not-so-smart/smart_git.mli @@ -1,110 +1,2 @@ -module type APPEND = sig - type 'a rd = < rd : unit ; .. > as 'a - type 'a wr = < wr : unit ; .. > as 'a - - type 'a mode = - | Rd : < rd : unit > mode - | Wr : < wr : unit > mode - | RdWr : < rd : unit ; wr : unit > mode - - type t - type uid - type 'a fd - type error - type +'a fiber - - val pp_error : error Fmt.t - val create : mode:'a mode -> t -> uid -> ('a fd, error) result fiber - val map : t -> 'm rd fd -> pos:int64 -> int -> Bigstringaf.t fiber - val append : t -> 'm wr fd -> string -> unit fiber - val move : t -> src:uid -> dst:uid -> (unit, error) result fiber - val close : t -> 'm fd -> (unit, error) result fiber -end - -module type UID = sig - include Carton.UID - include Sigs.UID with type t := t - - val hash : t -> int -end - -module type HTTP = sig - type error - - val pp_error : error Fmt.t - - val get : - ctx:Mimic.ctx -> - ?headers:(string * string) list -> - Uri.t -> - (unit * string, error) result Lwt.t - - val post : - ctx:Mimic.ctx -> - ?headers:(string * string) list -> - Uri.t -> - string -> - (unit * string, error) result Lwt.t -end - -module Endpoint : sig - type t = private { - scheme : - [ `SSH of string - | `Git - | `HTTP of (string * string) list - | `HTTPS of (string * string) list ]; - path : string; - host : [ `Addr of Ipaddr.t | `Domain of [ `host ] Domain_name.t ]; - } - - val pp : t Fmt.t - val of_string : string -> (t, [> `Msg of string ]) result - - val with_headers_if_http : (string * string) list -> t -> t - (** [with_headers_if_http hdrs edn] if endpoint [edn] is [`HTTP] or [`HTTPS] - adds [hdrs] to [edn] *) -end - -module Make - (Scheduler : Sigs.SCHED with type +'a s = 'a Lwt.t) - (Pack : APPEND with type +'a fiber = 'a Lwt.t) - (Index : APPEND with type +'a fiber = 'a Lwt.t) - (HTTP : HTTP) - (Uid : UID) - (Ref : Sigs.REF) : sig - val fetch : - ?push_stdout:(string -> unit) -> - ?push_stderr:(string -> unit) -> - ctx:Mimic.ctx -> - (Uid.t, _, Uid.t * int ref * int64, 'g, Scheduler.t) Sigs.access - * Uid.t Carton_lwt.Thin.light_load - * Uid.t Carton_lwt.Thin.heavy_load -> - (Uid.t, Uid.t * int ref * int64, 'g) Sigs.store -> - Endpoint.t -> - ?version:[> `V1 ] -> - ?capabilities:Smart.Capability.t list -> - ?deepen:[ `Depth of int | `Timestamp of int64 ] -> - [ `All | `Some of Ref.t list | `None ] -> - Pack.t -> - Index.t -> - src:Pack.uid -> - dst:Pack.uid -> - idx:Index.uid -> - ( [ `Pack of Uid.t * (Ref.t * Uid.t) list | `Empty ], - ([> `Exn of exn | Mimic.error ] as 'err) ) - result - Lwt.t - - val push : - ctx:Mimic.ctx -> - (Uid.t, Ref.t, Uid.t Pck.t, 'g, Scheduler.t) Sigs.access - * Uid.t Carton_lwt.Thin.light_load - * Uid.t Carton_lwt.Thin.heavy_load -> - (Uid.t, Uid.t Pck.t, 'g) Sigs.store -> - Endpoint.t -> - ?version:[> `V1 ] -> - ?capabilities:Smart.Capability.t list -> - [ `Create of Ref.t | `Delete of Ref.t | `Update of Ref.t * Ref.t ] list -> - (unit, ([> `Exn of exn | Mimic.error ] as 'err)) result Lwt.t -end +include Smart_git_intf.SMART_GIT +(** @inline *) diff --git a/src/not-so-smart/smart_git_intf.ml b/src/not-so-smart/smart_git_intf.ml new file mode 100644 index 000000000..7ee5a5779 --- /dev/null +++ b/src/not-so-smart/smart_git_intf.ml @@ -0,0 +1,116 @@ +module type APPEND = sig + type 'a rd = < rd : unit ; .. > as 'a + type 'a wr = < wr : unit ; .. > as 'a + + type 'a mode = + | Rd : < rd : unit > mode + | Wr : < wr : unit > mode + | RdWr : < rd : unit ; wr : unit > mode + + type t + type uid + type 'a fd + type error + type +'a fiber + + val pp_error : error Fmt.t + val create : mode:'a mode -> t -> uid -> ('a fd, error) result fiber + val map : t -> 'm rd fd -> pos:int64 -> int -> Bigstringaf.t fiber + val append : t -> 'm wr fd -> string -> unit fiber + val move : t -> src:uid -> dst:uid -> (unit, error) result fiber + val close : t -> 'm fd -> (unit, error) result fiber +end + +module type UID = sig + include Carton.UID + include Sigs.UID with type t := t + + val hash : t -> int +end + +module type HTTP = sig + type error + + val pp_error : error Fmt.t + + val get : + ctx:Mimic.ctx -> + ?headers:(string * string) list -> + Uri.t -> + (unit * string, error) result Lwt.t + + val post : + ctx:Mimic.ctx -> + ?headers:(string * string) list -> + Uri.t -> + string -> + (unit * string, error) result Lwt.t +end + +module type SMART_GIT = sig + module type APPEND = APPEND + module type UID = UID + module type HTTP = HTTP + + module Endpoint : sig + type t = private { + scheme : + [ `SSH of string + | `Git + | `HTTP of (string * string) list + | `HTTPS of (string * string) list ]; + path : string; + host : [ `Addr of Ipaddr.t | `Domain of [ `host ] Domain_name.t ]; + } + + val pp : t Fmt.t + val of_string : string -> (t, [> `Msg of string ]) result + + val with_headers_if_http : (string * string) list -> t -> t + (** [with_headers_if_http hdrs edn] if endpoint [edn] is [`HTTP] or [`HTTPS] + adds [hdrs] to [edn] *) + end + + module Make + (Scheduler : Sigs.SCHED with type +'a s = 'a Lwt.t) + (Pack : APPEND with type +'a fiber = 'a Lwt.t) + (Index : APPEND with type +'a fiber = 'a Lwt.t) + (HTTP : HTTP) + (Uid : UID) + (Ref : Sigs.REF) : sig + val fetch : + ?push_stdout:(string -> unit) -> + ?push_stderr:(string -> unit) -> + ctx:Mimic.ctx -> + (Uid.t, _, Uid.t * int ref * int64, 'g, Scheduler.t) Sigs.access + * Uid.t Carton_lwt.Thin.light_load + * Uid.t Carton_lwt.Thin.heavy_load -> + (Uid.t, Uid.t * int ref * int64, 'g) Sigs.store -> + Endpoint.t -> + ?version:[> `V1 ] -> + ?capabilities:Smart.Capability.t list -> + ?deepen:[ `Depth of int | `Timestamp of int64 ] -> + [ `All | `Some of Ref.t list | `None ] -> + Pack.t -> + Index.t -> + src:Pack.uid -> + dst:Pack.uid -> + idx:Index.uid -> + ( [ `Pack of Uid.t * (Ref.t * Uid.t) list | `Empty ], + ([> `Exn of exn | Mimic.error ] as 'err) ) + result + Lwt.t + + val push : + ctx:Mimic.ctx -> + (Uid.t, Ref.t, Uid.t Pck.t, 'g, Scheduler.t) Sigs.access + * Uid.t Carton_lwt.Thin.light_load + * Uid.t Carton_lwt.Thin.heavy_load -> + (Uid.t, Uid.t Pck.t, 'g) Sigs.store -> + Endpoint.t -> + ?version:[> `V1 ] -> + ?capabilities:Smart.Capability.t list -> + [ `Create of Ref.t | `Delete of Ref.t | `Update of Ref.t * Ref.t ] list -> + (unit, ([> `Exn of exn | Mimic.error ] as 'err)) result Lwt.t + end +end From c1c84187b790b6ce1b98e401ca8c8038623eed2f Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Fri, 8 Jan 2021 17:43:56 +0500 Subject: [PATCH 02/17] remove function-local vars from the module namespace --- src/not-so-smart/fetch.ml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/not-so-smart/fetch.ml b/src/not-so-smart/fetch.ml index 1089c0e38..958f57192 100644 --- a/src/not-so-smart/fetch.ml +++ b/src/not-so-smart/fetch.ml @@ -29,9 +29,8 @@ module Make struct open Scheduler - let src = Logs.Src.create "fetch" - - module Log = (val Logs.src_log src : Logs.LOG) + module Log = (val let src = Logs.Src.create "fetch" in + Logs.src_log src : Logs.LOG) let ( >>= ) x f = IO.bind x f let return x = IO.return x From 62ddb1ff4fb7ca0abacce87bb959d019aa157690 Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Fri, 8 Jan 2021 17:44:03 +0500 Subject: [PATCH 03/17] minor --- src/not-so-smart/smart_git.ml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/not-so-smart/smart_git.ml b/src/not-so-smart/smart_git.ml index 3bdfb290c..b3eb0ea77 100644 --- a/src/not-so-smart/smart_git.ml +++ b/src/not-so-smart/smart_git.ml @@ -123,17 +123,18 @@ struct let fs = let open Rresult in let open Lwt.Infix in - { - Thin.create = - (fun t path -> - Pack.create ~mode:Pack.RdWr t path - >|= R.reword_error (R.msgf "%a" Pack.pp_error)); - Thin.append = Pack.append; - Thin.map = Pack.map; - Thin.close = - (fun t fd -> - Pack.close t fd >|= R.reword_error (R.msgf "%a" Pack.pp_error)); - } + Thin. + { + create = + (fun t path -> + Pack.create ~mode:Pack.RdWr t path + >|= R.reword_error (R.msgf "%a" Pack.pp_error)); + append = Pack.append; + map = Pack.map; + close = + (fun t fd -> + Pack.close t fd >|= R.reword_error (R.msgf "%a" Pack.pp_error)); + } (* XXX(dinosaure): abstract it? *) let digest : From bb6437f73c86afc714f6f24fea96b0d1c6de5dfc Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Wed, 13 Jan 2021 21:58:25 +0500 Subject: [PATCH 04/17] fix up 'State.Context.is_cap_shared': * remove it from 'State.Context' module type as it's not necessary there * make it "t-first" as other fns for cap management --- src/not-so-smart/fetch.ml | 4 ++-- src/not-so-smart/push.ml | 6 +++--- src/not-so-smart/smart.mli | 2 +- src/not-so-smart/state.ml | 3 +-- src/not-so-smart/state.mli | 5 ++++- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/not-so-smart/fetch.ml b/src/not-so-smart/fetch.ml index 958f57192..761ce4e43 100644 --- a/src/not-so-smart/fetch.ml +++ b/src/not-so-smart/fetch.ml @@ -112,8 +112,8 @@ struct let pack ctx = let open Smart in let side_band = - Smart.Context.is_cap_shared `Side_band ctx - || Smart.Context.is_cap_shared `Side_band_64k ctx + Smart.Context.is_cap_shared ctx `Side_band + || Smart.Context.is_cap_shared ctx `Side_band_64k in recv ctx (recv_pack ~side_band ~push_stdout ~push_stderr ~push_pack:pack) diff --git a/src/not-so-smart/push.ml b/src/not-so-smart/push.ml index 3992dc1b6..8e269ec84 100644 --- a/src/not-so-smart/push.ml +++ b/src/not-so-smart/push.ml @@ -84,15 +84,15 @@ struct m "Prepare a pack of %d object(s)." (List.length uids)); let stream = pack uids in let side_band = - Smart.Context.is_cap_shared `Side_band ctx - || Smart.Context.is_cap_shared `Side_band_64k ctx + Smart.Context.is_cap_shared ctx `Side_band + || Smart.Context.is_cap_shared ctx `Side_band_64k in let pack = Smart.send_pack ~stateless:push_cfg.stateless side_band in let rec go () = stream () >>= function | None -> let report_status = - Smart.Context.is_cap_shared `Report_status ctx + Smart.Context.is_cap_shared ctx `Report_status in Log.debug (fun m -> m "report-status capability: %b." report_status); diff --git a/src/not-so-smart/smart.mli b/src/not-so-smart/smart.mli index df0248cc3..603a2a411 100644 --- a/src/not-so-smart/smart.mli +++ b/src/not-so-smart/smart.mli @@ -196,7 +196,7 @@ module Context : sig val make : Capability.t list -> t val update : t -> Capability.t list -> unit - val is_cap_shared : Capability.t -> t -> bool + val is_cap_shared : t -> Capability.t -> bool val capabilities : t -> Capability.t list * Capability.t list end diff --git a/src/not-so-smart/state.ml b/src/not-so-smart/state.ml index 534a353ef..f52e5336b 100644 --- a/src/not-so-smart/state.ml +++ b/src/not-so-smart/state.ml @@ -20,7 +20,6 @@ module type CONTEXT = sig val pp : t Fmt.t val encoder : t -> encoder val decoder : t -> decoder - val is_cap_shared : Capability.t -> t -> bool end module type S = sig @@ -62,7 +61,7 @@ module Context = struct let update ({ capabilities = client_side, _; _ } as t) server_side = t.capabilities <- client_side, server_side - let is_cap_shared capability t = + let is_cap_shared t capability = let client_side, server_side = t.capabilities in let a = List.exists (Capability.equal capability) client_side in a && List.exists (Capability.equal capability) server_side diff --git a/src/not-so-smart/state.mli b/src/not-so-smart/state.mli index 96994f163..d68ef0680 100644 --- a/src/not-so-smart/state.mli +++ b/src/not-so-smart/state.mli @@ -10,6 +10,7 @@ type ('a, 'err) t = | Return of 'a | Error of 'err +(** minimal interface that contains [encoder] and [decoder] states *) module type CONTEXT = sig type t type encoder @@ -18,7 +19,6 @@ module type CONTEXT = sig val pp : t Fmt.t val encoder : t -> encoder val decoder : t -> decoder - val is_cap_shared : Capability.t -> t -> bool end module type S = sig @@ -41,8 +41,11 @@ module Context : sig and type decoder = Decoder.decoder val make : Capability.t list -> t + (** [make caps] creates [Context.t] with client's capabilities [caps] *) + val capabilities : t -> Capability.t list * Capability.t list val update : t -> Capability.t list -> unit + val is_cap_shared : t -> Capability.t -> bool end module Scheduler From 43e993859f03efd94f6eec2977998054ffc9ca38 Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Wed, 13 Jan 2021 22:06:22 +0500 Subject: [PATCH 05/17] rename 'pusher' to 'pusher_with_logging' to reflect the changes --- src/not-so-smart/smart_git.ml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/not-so-smart/smart_git.ml b/src/not-so-smart/smart_git.ml index b3eb0ea77..bad3ff1f2 100644 --- a/src/not-so-smart/smart_git.ml +++ b/src/not-so-smart/smart_git.ml @@ -395,7 +395,7 @@ struct let host = edn.Endpoint.host in let path = edn.path in let stream, pusher = Lwt_stream.create () in - let pusher = function + let pusher_with_logging = function | Some (_, _, len) as v -> Log.debug (fun m -> m "Download %d byte(s) of the PACK file." len); pusher v @@ -415,7 +415,7 @@ struct Lwt.both (fetch_v1 ~push_stdout ~push_stderr ~uses_git_transport ~capabilities path ~ctx ?deepen ~want host store access - fetch_cfg pusher) + fetch_cfg pusher_with_logging) (run ~light_load ~heavy_load stream t_pck t_idx ~src ~dst ~idx) >>= fun (refs, idx) -> match refs, idx with @@ -446,7 +446,8 @@ struct let run () = Lwt.both (http_fetch_v1 ~push_stdout ~push_stderr ~capabilities ~ctx uri - ~headers host path ?deepen ~want store access fetch_cfg pusher) + ~headers host path ?deepen ~want store access fetch_cfg + pusher_with_logging) (run ~light_load ~heavy_load stream t_pck t_idx ~src ~dst ~idx) >>= fun (refs, idx) -> match refs, idx with From 1cc625e182e3e657fc62dce9143a70d13bc41c17 Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Thu, 14 Jan 2021 12:14:57 +0500 Subject: [PATCH 06/17] simplify 'State.Scheduler.{reword_error; bind}' --- src/not-so-smart/state.ml | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/not-so-smart/state.ml b/src/not-so-smart/state.ml index f52e5336b..7a85096c3 100644 --- a/src/not-so-smart/state.ml +++ b/src/not-so-smart/state.ml @@ -76,21 +76,15 @@ struct type error = Value.error let bind : ('a, 'err) t -> f:('a -> ('b, 'err) t) -> ('b, 'err) t = - let rec aux ~f m = + let rec bind' m ~f = match m with | Return v -> f v - | Read { k; off; len; buffer; eof } -> - Read { k = aux ~f <.> k; off; len; buffer; eof = aux ~f <.> eof } - | Write { k; off; len; buffer } -> - Write { k = aux ~f <.> k; off; len; buffer } | Error _ as err -> err + | Read ({ k; eof; _ } as rd) -> + Read { rd with k = bind' ~f <.> k; eof = bind' ~f <.> eof } + | Write ({ k; _ } as wr) -> Write { wr with k = bind' ~f <.> k } in - fun m ~f -> - match m with - | Return v -> f v - | Error _ as err -> err - | Read _ -> aux ~f m - | Write _ -> aux ~f m + bind' let ( let* ) m f = bind m ~f let ( >>= ) m f = bind m ~f @@ -98,15 +92,14 @@ struct let fail error = Error error let reword_error f x = - let rec go = function - | Read { k; buffer; off; len; eof } -> - Read { k = go <.> k; buffer; off; len; eof = go <.> eof } - | Write { k; buffer; off; len } -> - Write { k = go <.> k; buffer; off; len } - | Return v -> Return v + let rec map_error = function + | Return _ as r -> r | Error err -> Error (f err) + | Read ({ k; eof; _ } as rd) -> + Read { rd with k = map_error <.> k; eof = map_error <.> eof } + | Write ({ k; _ } as wr) -> Write { wr with k = map_error <.> k } in - go x + map_error x let encode : type a. From e748c139e7485444eea1ca8f83c86bc8fe20638a Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Thu, 14 Jan 2021 12:21:41 +0500 Subject: [PATCH 07/17] avoid duplication in 'State.Scheduler.{encode; decode}' --- src/not-so-smart/state.ml | 41 ++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/not-so-smart/state.ml b/src/not-so-smart/state.ml index 7a85096c3..beecba930 100644 --- a/src/not-so-smart/state.ml +++ b/src/not-so-smart/state.ml @@ -101,6 +101,19 @@ struct in map_error x + (* Is slightly different from [m |> reword_error ~f >>= f1]. + The places where [apply] used currently the alternative code above would be sufficient, + but that would end up in twice the number of function calls *) + let apply m ~bind_ret ~bind_err = + let rec apply' = function + | Return r -> bind_ret r + | Error err -> bind_err err + | Read ({ k; eof; _ } as rd) -> + Read { rd with k = apply' <.> k; eof = apply' <.> eof } + | Write ({ k; _ } as wr) -> Write { wr with k = apply' <.> k } + in + apply' m + let encode : type a. Context.t -> @@ -109,15 +122,11 @@ struct (Context.t -> ('b, [> `Protocol of error ]) t) -> ('b, [> `Protocol of error ]) t = fun ctx w v k -> - let rec go = function - | Return () -> k ctx - | Write { k; buffer; off; len } -> - Write { k = go <.> k; buffer; off; len } - | Read { k; buffer; off; len; eof } -> - Read { k = go <.> k; buffer; off; len; eof = go <.> eof } - | Error err -> Error (`Protocol err) - in - go (Value.encode (Context.encoder ctx) w v) + let encoder = Context.encoder ctx in + Value.encode encoder w v + |> apply + ~bind_ret:(fun () -> k ctx) + ~bind_err:(fun err -> Error (`Protocol err)) let send : type a. @@ -131,15 +140,11 @@ struct (Context.t -> a -> ('b, [> `Protocol of error ]) t) -> ('b, [> `Protocol of error ]) t = fun ctx w k -> - let rec go : (a, 'err) t -> ('b, [> `Protocol of error ]) t = function - | Read { k; buffer; off; len; eof } -> - Read { k = go <.> k; buffer; off; len; eof = go <.> eof } - | Write { k; buffer; off; len } -> - Write { k = go <.> k; buffer; off; len } - | Return v -> k ctx v - | Error err -> Error (`Protocol err) - in - go (Value.decode (Context.decoder ctx) w) + let decoder = Context.decoder ctx in + Value.decode decoder w + |> apply + ~bind_ret:(fun v -> k ctx v) + ~bind_err:(fun e -> Error (`Protocol e)) let recv : type a. Context.t -> a Value.recv -> (a, [> `Protocol of error ]) t = From 986918a7b7d98aed31022369b10cd34541c5bdaa Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Thu, 14 Jan 2021 12:22:06 +0500 Subject: [PATCH 08/17] inline redundant function --- src/not-so-smart/smart.ml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/not-so-smart/smart.ml b/src/not-so-smart/smart.ml index cd595c9fd..52ea103bb 100644 --- a/src/not-so-smart/smart.ml +++ b/src/not-so-smart/smart.ml @@ -53,9 +53,9 @@ module Value = struct let encode : type a. encoder -> a send -> a -> (unit, [> Encoder.error ]) State.t = fun encoder w v -> - let fiber : a send -> [> Encoder.error ] Encoder.state = + let encoder_state = let open Protocol.Encoder in - function + match w with | Proto_request -> encode_proto_request encoder v | Want -> encode_want encoder v | Done -> encode_done encoder @@ -65,13 +65,14 @@ module Value = struct | Flush -> encode_flush encoder | Advertised_refs -> encode_advertised_refs encoder v in - let rec go = function + let rec translate_to_state_t = function | Encoder.Done -> State.Return () | Write { continue; buffer; off; len } -> - State.Write { k = go <.> continue; buffer; off; len } + State.Write + { k = translate_to_state_t <.> continue; buffer; off; len } | Error err -> State.Error (err :> error) in - (go <.> fiber) w + translate_to_state_t encoder_state let decode : type a. decoder -> a recv -> (a, [> Decoder.error ]) State.t = fun decoder w -> From d8239edb27dfcc5003c8d86b2dccf474b4278943 Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Thu, 14 Jan 2021 12:29:31 +0500 Subject: [PATCH 09/17] rename 'State.S' to 'State.VALUE' as that module type is used to type module named 'Value' and doesn't reflect the module type of 'State', though 'S' usually should do that --- src/not-so-smart/state.ml | 4 ++-- src/not-so-smart/state.mli | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/not-so-smart/state.ml b/src/not-so-smart/state.ml index beecba930..e44057a74 100644 --- a/src/not-so-smart/state.ml +++ b/src/not-so-smart/state.ml @@ -22,7 +22,7 @@ module type CONTEXT = sig val decoder : t -> decoder end -module type S = sig +module type VALUE = sig type 'a send type 'a recv type error @@ -69,7 +69,7 @@ end module Scheduler (Context : CONTEXT) - (Value : S + (Value : VALUE with type encoder = Context.encoder and type decoder = Context.decoder) = struct diff --git a/src/not-so-smart/state.mli b/src/not-so-smart/state.mli index d68ef0680..fa6748125 100644 --- a/src/not-so-smart/state.mli +++ b/src/not-so-smart/state.mli @@ -21,7 +21,7 @@ module type CONTEXT = sig val decoder : t -> decoder end -module type S = sig +module type VALUE = sig type 'a send type 'a recv type error @@ -50,7 +50,7 @@ end module Scheduler (Context : CONTEXT) - (Value : S + (Value : VALUE with type encoder = Context.encoder and type decoder = Context.decoder) : sig type error = Value.error From 905b1bcc78bccff39245a1fb03e58589e6b388f0 Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Thu, 14 Jan 2021 17:41:53 +0500 Subject: [PATCH 10/17] remove 'open Stdlib' lines as unnecessary --- src/git-index/git_index.ml | 1 - src/git-unix/git_unix.ml | 1 - src/git/cstruct_append.ml | 2 -- src/git/value.ml | 2 -- src/not-so-smart/capability.ml | 2 -- src/not-so-smart/find_common.ml | 1 - src/not-so-smart/protocol.ml | 2 -- test/carton/test.ml | 2 -- 8 files changed, 13 deletions(-) diff --git a/src/git-index/git_index.ml b/src/git-index/git_index.ml index 59ac6ebb5..d837f7b8c 100644 --- a/src/git-index/git_index.ml +++ b/src/git-index/git_index.ml @@ -1,6 +1,5 @@ [@@@warning "-32"] -open Stdlib module Bigarray = Bigarray_compat let io_buffer_size = 65536 diff --git a/src/git-unix/git_unix.ml b/src/git-unix/git_unix.ml index 52db45810..7f1fc562d 100644 --- a/src/git-unix/git_unix.ml +++ b/src/git-unix/git_unix.ml @@ -15,7 +15,6 @@ *) module Bigarray = Bigarray_compat -open Stdlib open Lwt.Infix let ( >>? ) x f = diff --git a/src/git/cstruct_append.ml b/src/git/cstruct_append.ml index b71f5b1bd..65b84ce52 100644 --- a/src/git/cstruct_append.ml +++ b/src/git/cstruct_append.ml @@ -7,8 +7,6 @@ In this context, [t] can stores only 2 objects. We should extend the implementation to be more general but the trade-off is bad. *) -open Stdlib - let src = Logs.Src.create "git-cstruct-append" module Log = (val Logs.src_log src : Logs.LOG) diff --git a/src/git/value.ml b/src/git/value.ml index 3807b1b2f..11c428bac 100644 --- a/src/git/value.ml +++ b/src/git/value.ml @@ -15,8 +15,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) -open Stdlib - type 'hash t = | Blob of Blob.t | Commit of 'hash Commit.t diff --git a/src/not-so-smart/capability.ml b/src/not-so-smart/capability.ml index ad72df605..cf770f03c 100644 --- a/src/not-so-smart/capability.ml +++ b/src/not-so-smart/capability.ml @@ -1,5 +1,3 @@ -open Stdlib - type t = [ `Multi_ack | `Multi_ack_detailed diff --git a/src/not-so-smart/find_common.ml b/src/not-so-smart/find_common.ml index 024994902..ccf93d62d 100644 --- a/src/not-so-smart/find_common.ml +++ b/src/not-so-smart/find_common.ml @@ -1,5 +1,4 @@ open Sigs -open Stdlib let ( <.> ) f g x = f (g x) let src = Logs.Src.create "find-common" diff --git a/src/not-so-smart/protocol.ml b/src/not-so-smart/protocol.ml index a29d616b8..4e3bf3786 100644 --- a/src/not-so-smart/protocol.ml +++ b/src/not-so-smart/protocol.ml @@ -1,7 +1,5 @@ let ( <.> ) f g x = f (g x) -open Stdlib - module Advertised_refs = struct type ('uid, 'reference) t = { shallows : 'uid list; diff --git a/test/carton/test.ml b/test/carton/test.ml index 7a0aa022c..06e1e9f6d 100644 --- a/test/carton/test.ml +++ b/test/carton/test.ml @@ -1,7 +1,5 @@ let () = Printexc.record_backtrace true -open Stdlib - let weights = Alcotest.test_case "weight" `Quick @@ fun () -> Alcotest.(check int) "0" (Carton.Dec.null :> int) 0; From e1eff6047f0d5107ddbeb5a23c51826a4735d309 Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Thu, 14 Jan 2021 17:43:17 +0500 Subject: [PATCH 11/17] fix confusing naming: 'f' is too close to a function --- src/not-so-smart/find_common.ml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/not-so-smart/find_common.ml b/src/not-so-smart/find_common.ml index ccf93d62d..deb5421f2 100644 --- a/src/not-so-smart/find_common.ml +++ b/src/not-so-smart/find_common.ml @@ -15,11 +15,11 @@ type ('a, 's) raise = exn -> ('a, 's) io let io_buffer_size = 65536 let run : - type f s. + type fl s. s scheduler -> ('a, s) raise -> - (f, 'error, s) flow -> - f -> + (fl, 'error, s) flow -> + fl -> ('res, [ `Protocol of Smart.error ]) Smart.t -> ('res, s) io = fun { bind; return } raise { recv; send; pp_error } flow fiber -> From a5ce20ea7654502b8f0d32889f64a1dd9a8bab7b Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Thu, 14 Jan 2021 17:44:04 +0500 Subject: [PATCH 12/17] remove code duplication with some verbosity --- src/not-so-smart/smart.ml | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/not-so-smart/smart.ml b/src/not-so-smart/smart.ml index 52ea103bb..7813c9d3d 100644 --- a/src/not-so-smart/smart.ml +++ b/src/not-so-smart/smart.ml @@ -76,22 +76,26 @@ module Value = struct let decode : type a. decoder -> a recv -> (a, [> Decoder.error ]) State.t = fun decoder w -> - let rec go = function + let rec transl : + (a, [> Protocol.Decoder.error ]) Decoder.state -> + (a, [> Decoder.error ]) State.t = function | Decoder.Done v -> State.Return v | Read { buffer; off; len; continue; eof } -> - State.Read { k = go <.> continue; buffer; off; len; eof = go <.> eof } + State.Read + { k = transl <.> continue; buffer; off; len; eof = transl <.> eof } | Error { error; _ } -> State.Error error in - let open Protocol.Decoder in - match w with - | Advertised_refs -> go (decode_advertised_refs decoder) - | Result -> go (decode_result decoder) - | Recv_pack { side_band; push_pack; push_stdout; push_stderr } -> - go (decode_pack ~side_band ~push_pack ~push_stdout ~push_stderr decoder) - | Ack -> go (decode_negotiation decoder) - | Status -> go (decode_status decoder) - | Shallows -> go (decode_shallows decoder) - | Packet trim -> go (decode_packet ~trim decoder) + transl + (let open Protocol.Decoder in + match w with + | Advertised_refs -> decode_advertised_refs decoder + | Result -> decode_result decoder + | Recv_pack { side_band; push_pack; push_stdout; push_stderr } -> + decode_pack ~side_band ~push_pack ~push_stdout ~push_stderr decoder + | Ack -> decode_negotiation decoder + | Status -> decode_status decoder + | Shallows -> decode_shallows decoder + | Packet trim -> decode_packet ~trim decoder) end type ('a, 'err) t = ('a, 'err) State.t = From 77daa7c24d968545ca4e91470135aa84016f3fd9 Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Thu, 14 Jan 2021 18:18:57 +0500 Subject: [PATCH 13/17] easier 'unsafe_encode_packet' --- src/not-so-smart/protocol.ml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/not-so-smart/protocol.ml b/src/not-so-smart/protocol.ml index 4e3bf3786..c51f7bb85 100644 --- a/src/not-so-smart/protocol.ml +++ b/src/not-so-smart/protocol.ml @@ -857,12 +857,11 @@ module Encoder = struct in delayed_write_pkt k kdone encoder - let unsafe_encode_packet encoder ~packet = - let pos = encoder.pos in - encoder.pos <- encoder.pos + 4; + let unsafe_encode_packet ({ pos; payload; _ } as encoder) ~packet = + encoder.pos <- pos + 4; write encoder packet; let len = encoder.pos - pos in - Bytes.blit_string (Fmt.str "%04X" len) 0 encoder.payload pos 4 + Bytes.blit_string (Fmt.str "%04X" len) 0 payload pos 4 let write_command encoder = function | Commands.Create (uid, r) -> From faeb74322d44594b3b8f7f66eac8b95f2fb87516 Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Fri, 15 Jan 2021 00:24:53 +0500 Subject: [PATCH 14/17] clean namespace slightly --- src/not-so-smart/find_common.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/not-so-smart/find_common.ml b/src/not-so-smart/find_common.ml index deb5421f2..fb6bf5835 100644 --- a/src/not-so-smart/find_common.ml +++ b/src/not-so-smart/find_common.ml @@ -1,9 +1,9 @@ open Sigs let ( <.> ) f g x = f (g x) -let src = Logs.Src.create "find-common" -module Log = (val Logs.src_log src : Logs.LOG) +module Log = (val let src = Logs.Src.create "find-common" in + Logs.src_log src : Logs.LOG) let _initial_flush = 16 let _max_in_vain = 256 From 906ae7b07769de1c16b9df773ef048d40b867e20 Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Fri, 15 Jan 2021 00:46:25 +0500 Subject: [PATCH 15/17] move 'run' fn in nss 'Neg' to its own sub-library 'git.nss.smart-flow' --- src/not-so-smart/dune | 12 ++++++-- src/not-so-smart/fetch.ml | 7 +++-- src/not-so-smart/find_common.ml | 49 +------------------------------ src/not-so-smart/neg.ml | 3 -- src/not-so-smart/neg.mli | 9 ------ src/not-so-smart/push.ml | 12 ++++---- src/not-so-smart/smart_flow.ml | 52 +++++++++++++++++++++++++++++++++ src/not-so-smart/smart_flow.mli | 13 +++++++++ 8 files changed, 87 insertions(+), 70 deletions(-) create mode 100644 src/not-so-smart/smart_flow.ml create mode 100644 src/not-so-smart/smart_flow.mli diff --git a/src/not-so-smart/dune b/src/not-so-smart/dune index d73fafd8a..b8eb41ca1 100644 --- a/src/not-so-smart/dune +++ b/src/not-so-smart/dune @@ -17,6 +17,12 @@ (modules sigs) (libraries fmt cstruct)) +(library + (name smart_flow) + (public_name git.nss.smart-flow) + (modules smart_flow) + (libraries cstruct fmt git.nss.sigs git.nss.smart logs)) + (library (name hkt) (public_name git.nss.hkt) @@ -27,7 +33,8 @@ (name neg) (public_name git.nss.neg) (modules neg find_common default) - (libraries stdlib-shims fmt rresult cstruct sigs logs psq smart)) + (libraries stdlib-shims fmt rresult cstruct sigs logs psq smart + git.nss.smart-flow)) (library (name pck) @@ -39,7 +46,8 @@ (name nss) (public_name git.nss) (modules nss fetch push) - (libraries fmt result rresult logs ipaddr domain-name smart sigs neg pck)) + (libraries fmt result rresult logs ipaddr domain-name smart sigs neg pck + git.nss.smart-flow)) (library (name unixiz) diff --git a/src/not-so-smart/fetch.ml b/src/not-so-smart/fetch.ml index 761ce4e43..9c804a893 100644 --- a/src/not-so-smart/fetch.ml +++ b/src/not-so-smart/fetch.ml @@ -99,7 +99,8 @@ struct let ctx = Smart.Context.make capabilities in let negotiator = Neg.make ~compare:Uid.compare in Neg.tips sched access store negotiator |> prj >>= fun () -> - Neg.run sched fail io flow (prelude ctx) |> prj >>= fun (uids, refs) -> + Smart_flow.run sched fail io flow (prelude ctx) |> prj + >>= fun (uids, refs) -> let hex = { Neg.to_hex = Uid.to_hex; of_hex = Uid.of_hex; compare = Uid.compare } in @@ -121,8 +122,8 @@ struct if res < 0 then Log.warn (fun m -> m "No common commits"); let rec go () = Log.debug (fun m -> m "Read PACK file."); - Neg.run sched fail io flow (pack ctx) |> prj >>= fun continue -> - if continue then go () else return () + Smart_flow.run sched fail io flow (pack ctx) |> prj + >>= fun continue -> if continue then go () else return () in Log.debug (fun m -> m "Start to download PACK file."); go () >>= fun () -> return (List.combine refs uids) diff --git a/src/not-so-smart/find_common.ml b/src/not-so-smart/find_common.ml index fb6bf5835..5289b4df1 100644 --- a/src/not-so-smart/find_common.ml +++ b/src/not-so-smart/find_common.ml @@ -1,4 +1,5 @@ open Sigs +open Smart_flow let ( <.> ) f g x = f (g x) @@ -10,54 +11,6 @@ let _max_in_vain = 256 let _large_flush = 16384 let _pipe_safe_flush = 32 -type ('a, 's) raise = exn -> ('a, 's) io - -let io_buffer_size = 65536 - -let run : - type fl s. - s scheduler -> - ('a, s) raise -> - (fl, 'error, s) flow -> - fl -> - ('res, [ `Protocol of Smart.error ]) Smart.t -> - ('res, s) io = - fun { bind; return } raise { recv; send; pp_error } flow fiber -> - let ( >>= ) = bind in - let tmp = Cstruct.create io_buffer_size in - let failwithf fmt = Format.kasprintf (fun err -> raise (Failure err)) fmt in - let rec go = function - | Smart.Read { k; buffer; off; len; eof } -> ( - let max = min (Cstruct.len tmp) len in - Log.debug (fun m -> m "Start to read %d byte(s)." max); - recv flow (Cstruct.sub tmp 0 max) >>= function - | Ok `End_of_flow -> - Log.debug (fun m -> m "Got end of input."); - go (eof ()) - | Ok (`Input len) -> - Log.debug (fun m -> m "Got %d/%d byte(s)." len max); - Cstruct.blit_to_bytes tmp 0 buffer off len; - go (k len) - | Error err -> - Log.err (fun m -> m "Got an error: %a." pp_error err); - failwithf "%a" pp_error err) - | Smart.Write { k; buffer; off; len } -> - let rec loop tmp = - if Cstruct.len tmp = 0 then go (k len) - else - send flow tmp >>= function - | Ok shift -> loop (Cstruct.shift tmp shift) - | Error err -> failwithf "%a" pp_error err - in - Log.debug (fun m -> m "Write %d byte(s)." len); - loop (Cstruct.of_string buffer ~off ~len) - | Smart.Return v -> return v - | Smart.Error (`Protocol err) -> - Log.err (fun m -> m "Got a protocol error: %a." Smart.pp_error err); - failwithf "%a" Smart.pp_error err - in - go fiber - (* XXX(dinosaure): this part is really **ugly**! But we must follow the same behaviour of [git]. Instead to understand the synchronisation process of [git] with Smart.v1 and implement a state of the art synchronisation algorithm, I diff --git a/src/not-so-smart/neg.ml b/src/not-so-smart/neg.ml index 38e4c5b98..cb2ff9a8f 100644 --- a/src/not-so-smart/neg.ml +++ b/src/not-so-smart/neg.ml @@ -1,5 +1,3 @@ -type nonrec ('a, 's) raise = ('a, 's) Find_common.raise - type nonrec configuration = Find_common.configuration = { stateless : bool; mutable multi_ack : [ `None | `Some | `Detailed ]; @@ -15,6 +13,5 @@ type nonrec 'uid hex = 'uid Find_common.hex = { type 'uid negotiator = 'uid Default.t let make ~compare = Default.make ~compare -let run = Find_common.run let find_common = Find_common.find_common let tips = Find_common.tips diff --git a/src/not-so-smart/neg.mli b/src/not-so-smart/neg.mli index 2691a53ac..d62ae0509 100644 --- a/src/not-so-smart/neg.mli +++ b/src/not-so-smart/neg.mli @@ -31,19 +31,10 @@ type 'uid hex = { compare : 'uid -> 'uid -> int; } -type ('a, 's) raise = exn -> ('a, 's) io type 'uid negotiator val make : compare:('uid -> 'uid -> int) -> 'uid negotiator -val run : - 's scheduler -> - ('res, 's) raise -> - ('flow, 'error, 's) flow -> - 'flow -> - ('res, [ `Protocol of Smart.error ]) Smart.t -> - ('res, 's) io - val find_common : 's scheduler -> ('flow, 'error, 's) flow -> diff --git a/src/not-so-smart/push.ml b/src/not-so-smart/push.ml index 8e269ec84..fbdd29ca0 100644 --- a/src/not-so-smart/push.ml +++ b/src/not-so-smart/push.ml @@ -54,7 +54,8 @@ struct return (Smart.Advertised_refs.map ~fuid:Uid.of_hex ~fref:Ref.v v) in let ctx = Smart.Context.make caps in - Neg.run sched fail io flow (fiber ctx) |> prj >>= fun advertised_refs -> + Smart_flow.run sched fail io flow (fiber ctx) |> prj + >>= fun advertised_refs -> Pck.commands sched ~capabilities:(Smart.Advertised_refs.capabilities advertised_refs) ~equal:Ref.equal ~deref:access.Sigs.deref store cmds @@ -62,10 +63,10 @@ struct |> prj >>= function | None -> - Neg.run sched fail io flow Smart.(send ctx flush ()) |> prj + Smart_flow.run sched fail io flow Smart.(send ctx flush ()) |> prj >>= fun () -> return () | Some cmds -> ( - Neg.run sched fail io flow + Smart_flow.run sched fail io flow Smart.( send ctx commands (Commands.map ~fuid:Uid.to_hex ~fref:Ref.to_string cmds)) @@ -97,14 +98,15 @@ struct Log.debug (fun m -> m "report-status capability: %b." report_status); if report_status then - Neg.run sched fail io flow Smart.(recv ctx status) + Smart_flow.run sched fail io flow Smart.(recv ctx status) |> prj >>| Smart.Status.map ~f:Ref.v else let cmds = List.map R.ok (Smart.Commands.commands cmds) in return (Smart.Status.v cmds) | Some payload -> - Neg.run sched fail io flow Smart.(send ctx pack payload) |> prj + Smart_flow.run sched fail io flow Smart.(send ctx pack payload) + |> prj >>= fun () -> go () in go () >>= fun status -> diff --git a/src/not-so-smart/smart_flow.ml b/src/not-so-smart/smart_flow.ml new file mode 100644 index 000000000..1d70336ba --- /dev/null +++ b/src/not-so-smart/smart_flow.ml @@ -0,0 +1,52 @@ +open Sigs + +module Log = (val let src = Logs.Src.create "smart_flow" in + Logs.src_log src : Logs.LOG) + +let io_buffer_size = 65536 + +type ('a, 's) raise = exn -> ('a, 's) io + +let run : + type fl s. + s scheduler -> + ('a, s) raise -> + (fl, 'error, s) flow -> + fl -> + ('res, [ `Protocol of Smart.error ]) Smart.t -> + ('res, s) io = + fun { bind; return } raise { recv; send; pp_error } flow fiber -> + let ( >>= ) = bind in + let tmp = Cstruct.create io_buffer_size in + let failwithf fmt = Format.kasprintf (fun err -> raise (Failure err)) fmt in + let rec go = function + | Smart.Read { k; buffer; off; len; eof } -> ( + let max = min (Cstruct.len tmp) len in + Log.debug (fun m -> m "Start to read %d byte(s)." max); + recv flow (Cstruct.sub tmp 0 max) >>= function + | Ok `End_of_flow -> + Log.debug (fun m -> m "Got end of input."); + go (eof ()) + | Ok (`Input len) -> + Log.debug (fun m -> m "Got %d/%d byte(s)." len max); + Cstruct.blit_to_bytes tmp 0 buffer off len; + go (k len) + | Error err -> + Log.err (fun m -> m "Got an error: %a." pp_error err); + failwithf "%a" pp_error err) + | Smart.Write { k; buffer; off; len } -> + let rec loop tmp = + if Cstruct.len tmp = 0 then go (k len) + else + send flow tmp >>= function + | Ok shift -> loop (Cstruct.shift tmp shift) + | Error err -> failwithf "%a" pp_error err + in + Log.debug (fun m -> m "Write %d byte(s)." len); + loop (Cstruct.of_string buffer ~off ~len) + | Smart.Return v -> return v + | Smart.Error (`Protocol err) -> + Log.err (fun m -> m "Got a protocol error: %a." Smart.pp_error err); + failwithf "%a" Smart.pp_error err + in + go fiber diff --git a/src/not-so-smart/smart_flow.mli b/src/not-so-smart/smart_flow.mli new file mode 100644 index 000000000..fbcdcde6d --- /dev/null +++ b/src/not-so-smart/smart_flow.mli @@ -0,0 +1,13 @@ +open Sigs + +val io_buffer_size : int + +type ('a, 's) raise = exn -> ('a, 's) Sigs.io + +val run : + 's scheduler -> + ('res, 's) raise -> + ('flow, 'error, 's) flow -> + 'flow -> + ('res, [ `Protocol of Smart.error ]) Smart.t -> + ('res, 's) io From de51c70a85770fc6679d38a85064f47206fed41c Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Fri, 15 Jan 2021 13:57:51 +0500 Subject: [PATCH 16/17] rename 'prelude' to 'uses_git_transport' in 'git push' commands --- src/not-so-smart/push.ml | 6 +++--- src/not-so-smart/push.mli | 2 +- src/not-so-smart/smart_git.ml | 15 +++++++++------ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/not-so-smart/push.ml b/src/not-so-smart/push.ml index fbdd29ca0..3375c65a6 100644 --- a/src/not-so-smart/push.ml +++ b/src/not-so-smart/push.ml @@ -39,12 +39,12 @@ struct pp_error = Flow.pp_error; } - let push ?(prelude = true) ~capabilities:caps cmds ~host path flow store - access push_cfg pack = + let push ?(uses_git_transport = true) ~capabilities:caps cmds ~host path flow + store access push_cfg pack = let fiber ctx = let open Smart in let* () = - if prelude then + if uses_git_transport then send ctx proto_request (Proto_request.receive_pack ~host ~version:1 path) else return () diff --git a/src/not-so-smart/push.mli b/src/not-so-smart/push.mli index 9ee4c06a1..1c8cc5d99 100644 --- a/src/not-so-smart/push.mli +++ b/src/not-so-smart/push.mli @@ -11,7 +11,7 @@ module Make (Uid : UID) (Ref : REF) : sig val push : - ?prelude:bool -> + ?uses_git_transport:bool -> capabilities:Smart.Capability.t list -> [ `Create of Ref.t | `Delete of Ref.t | `Update of Ref.t * Ref.t ] list -> host:[ `Addr of Ipaddr.t | `Domain of [ `host ] Domain_name.t ] -> diff --git a/src/not-so-smart/smart_git.ml b/src/not-so-smart/smart_git.ml index bad3ff1f2..53fe635ce 100644 --- a/src/not-so-smart/smart_git.ml +++ b/src/not-so-smart/smart_git.ml @@ -554,12 +554,12 @@ struct Lwt.async fiber; stream - let push ?prelude ~ctx ~capabilities path cmds endpoint store access push_cfg - pack = + let push ?uses_git_transport ~ctx ~capabilities path cmds endpoint store + access push_cfg pack = let open Lwt.Infix in Mimic.resolve ctx >>? fun flow -> - Push.push ?prelude ~capabilities cmds ~host:endpoint path (Flow.make flow) - store access push_cfg pack + Push.push ?uses_git_transport ~capabilities cmds ~host:endpoint path + (Flow.make flow) store access push_cfg pack >>= fun () -> Mimic.close flow >>= fun () -> Lwt.return_ok () @@ -568,12 +568,15 @@ struct let open Rresult in match version, edn.Endpoint.scheme with | `V1, ((`Git | `SSH _) as scheme) -> - let prelude = match scheme with `Git -> true | `SSH _ -> false in + let uses_git_transport = + match scheme with `Git -> true | `SSH _ -> false + in let host = edn.host in let path = edn.path in let push_cfg = Nss.Push.configuration () in let run () = - push ~prelude ~ctx ~capabilities path cmds host store access push_cfg + push ~uses_git_transport ~ctx ~capabilities path cmds host store + access push_cfg (pack ~light_load ~heavy_load) in Lwt.catch run (function From 22c009a8767e40eff156a720111e0dcef13160e4 Mon Sep 17 00:00:00 2001 From: Ulugbek Abdullaev Date: Mon, 18 Jan 2021 12:15:22 +0500 Subject: [PATCH 17/17] make parsing lazier by using a lazier 'choice' fn for Result.t --- src/not-so-smart/smart_git.ml | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/not-so-smart/smart_git.ml b/src/not-so-smart/smart_git.ml index 53fe635ce..3f2d0904a 100644 --- a/src/not-so-smart/smart_git.ml +++ b/src/not-so-smart/smart_git.ml @@ -7,8 +7,6 @@ module Verbose = struct let print () = Lwt.return_unit end -let ( <.> ) f g x = f (g x) - module Endpoint = struct type t = { scheme : @@ -36,11 +34,10 @@ module Endpoint = struct | { scheme = `HTTPS _; path; host } -> Fmt.pf ppf "https://%a/%s" pp_host host path - let ( <|> ) a b = - match a, b with - | Ok a, _ -> Ok a - | Error _, Ok b -> Ok b - | Error err, _ -> Error err + let ( <||> ) a b = + match a with + | Ok _ -> a + | Error _ -> ( match b () with Ok _ as r -> r | Error _ -> a) let of_string str = let open Rresult in @@ -81,10 +78,9 @@ module Endpoint = struct let uri = Uri.of_string x in let path = Uri.path uri in let host str = - Domain_name.of_string str - >>= Domain_name.host - >>| (fun x -> `Domain x) - <|> (Ipaddr.of_string str >>| fun x -> `Addr x) + (Domain_name.of_string str >>= Domain_name.host >>| fun x -> `Domain x) + <||> fun () -> + Ipaddr.of_string str >>| fun x -> `Addr x in match Uri.scheme uri, Uri.host uri with | Some "git", Some str -> @@ -95,10 +91,9 @@ module Endpoint = struct host str >>= fun host -> R.ok { scheme = `HTTPS []; path; host } | _ -> R.error_msgf "invalid uri: %a" Uri.pp uri in - match parse_ssh str, parse_uri str with - | Ok edn, _ -> R.ok edn - | Error _, Ok edn -> R.ok edn - | Error _, Error _ -> R.error_msgf "Invalid endpoint: %s" str + parse_ssh str + <||> (fun () -> parse_uri str) + |> R.reword_error (fun _ -> R.msgf "Invalid endpoint: %s" str) let with_headers_if_http headers ({ scheme; _ } as edn) = match scheme with @@ -538,7 +533,7 @@ struct go 0 in encode_targets targets >>= fun () -> - let uid = Uid.((to_raw_string <.> get) !ctx) in + let uid = Uid.get !ctx |> Uid.to_raw_string in stream (Some uid); stream None; Lwt.return_unit