Complete the implementation with push and improve the documentation

This commit is contained in:
Romain Calascibetta 2022-10-24 10:44:21 +02:00
parent d49a406691
commit 30d5ad365a
2 changed files with 33 additions and 13 deletions

View file

@ -517,7 +517,7 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
let open Lwt.Infix in let open Lwt.Infix in
set ?push t key contents >|= Rresult.R.reword_error to_write_error set ?push t key contents >|= Rresult.R.reword_error to_write_error
let set_partial t key ~offset chunk = let set_partial ?push t key ~offset chunk =
let open Lwt_result.Infix in let open Lwt_result.Infix in
get t key >>= fun contents -> get t key >>= fun contents ->
let len = String.length contents in let len = String.length contents in
@ -525,7 +525,7 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
let res = Bytes.make (max len (offset + add)) '\000' in let res = Bytes.make (max len (offset + add)) '\000' in
Bytes.blit_string contents 0 res 0 len ; Bytes.blit_string contents 0 res 0 len ;
Bytes.blit_string chunk 0 res offset add ; Bytes.blit_string chunk 0 res offset add ;
set t key (Bytes.unsafe_to_string res) set ?push t key (Bytes.unsafe_to_string res)
let batch t ?retries:_ f = f t let batch t ?retries:_ f = f t
@ -592,6 +592,8 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
remove ~push t source >>= fun () -> remove ~push t source >>= fun () ->
set ~push t dest contents set ~push t dest contents
let set_partial_and_push t k ~offset v = set_partial ~push:true t k ~offset v
let set_partial t k ~offset v = set_partial ~push:false t k ~offset v
let set_and_push t k v = set ~push:true t k v let set_and_push t k v = set ~push:true t k v
let set t k v = set ~push:false t k v let set t k v = set ~push:false t k v
let remove_and_push t k = remove ~push:true t k let remove_and_push t k = remove ~push:true t k

View file

@ -3,7 +3,7 @@
This module implements the ability to manipulate a Git repository as a This module implements the ability to manipulate a Git repository as a
Key-Value store. It allows you to create a local (in-memory) Git repository Key-Value store. It allows you to create a local (in-memory) Git repository
that can come from either: that can come from either:
- a remote Git repository - a remote Git repository (with {!val:connect})
- a state serialized by the {!val:to_octets} function - a state serialized by the {!val:to_octets} function
The first case is interesting if you want to be synchronised with the The first case is interesting if you want to be synchronised with the
@ -13,20 +13,21 @@
In the second case, the synchronisation can be done later with {!val:pull}. In the second case, the synchronisation can be done later with {!val:pull}.
As far as {!val:push} is concerned, a synchronisation with the remote The user can modify the repository (add files, remove files, etc.). He can
repository is necessary before {b changing} and sending the new information do this locally and thus assume a possible desynchronisation between the
(a use of {!val:Make.set}/{!val:Make.rename} should be preceded by a remote repository and what exists locally or he can share these changes
{!val:pull}). This is because we do not handle conflicts that may exist with the remote repository with [{set,rename,remove}_and_push].
between your local repository and the remote repository - in other words,
if you want to ensure consistency between reading ({!val:pull}) and writing In the latter case, the notion of {i merge} and conflicts is not handled by
({!val:push}) to a remote repository, the instance that uses this code our implementation. This means that if the remote repository is manipulated
should be the only one to handle said remote repository. *) by another instance than yours, it can result in conflicts that will make
the above functions fail. *)
type t type t
(** The type of the Git store. *) (** The type of the Git store. *)
val connect : Mimic.ctx -> string -> t Lwt.t val connect : Mimic.ctx -> string -> t Lwt.t
(** [connect ctx remote] creates a new Git store which synchronizes (** [connect ctx remote] creates a new Git store which synchronises
with [remote] {i via} protocols available into the given [ctx]. with [remote] {i via} protocols available into the given [ctx].
@raise [Invalid_argument _] if we can not initialize the store, or if @raise [Invalid_argument _] if we can not initialize the store, or if
@ -47,7 +48,7 @@ type change = [ `Add of Mirage_kv.Key.t
| `Change of Mirage_kv.Key.t ] | `Change of Mirage_kv.Key.t ]
val pull : t -> (change list, [> `Msg of string ]) result Lwt.t val pull : t -> (change list, [> `Msg of string ]) result Lwt.t
(** [pull store] tries to synchronize the remote Git repository with your local (** [pull store] tries to synchronise the remote Git repository with your local
[store] Git repository. It returns a list of changes between the old state [store] Git repository. It returns a list of changes between the old state
of your store and what you have remotely. *) of your store and what you have remotely. *)
@ -60,6 +61,23 @@ module Make (Pclock : Mirage_clock.PCLOCK) : sig
| Mirage_kv.write_error ] | Mirage_kv.write_error ]
val set_and_push : t -> key -> string -> (unit, write_error) result Lwt.t val set_and_push : t -> key -> string -> (unit, write_error) result Lwt.t
(** [set_and_push t k v] replaces the binding [k -> v] in [t] and pushes this
modification to the remote repository. This function can fail on the
synchronisation mechanism if the remote Git repository is {i in advance}
of your local repository. It is advisable to use {!val:pull} before. *)
val remove_and_push : t -> key -> (unit, write_error) result Lwt.t val remove_and_push : t -> key -> (unit, write_error) result Lwt.t
(** Same as {!val:remove} with the synchronisation mechanism, see
{!val:set_and_push} for more details about possible failures and how to
use it. *)
val rename_and_push : t -> source:key -> dest:key -> (unit, write_error) result Lwt.t val rename_and_push : t -> source:key -> dest:key -> (unit, write_error) result Lwt.t
(** Same as {!val:rename} with the synchronisation mechanism, see
{!val:rename_and_push} for more details about possible failures and how
to use it. *)
val set_partial_and_push : t -> key -> offset:int -> string -> (unit, write_error) result Lwt.t
(** Same as {!val:set_partial} with the synchronisation mechanism, see
{!val:set_and_push} for more details about possible failures and how to
use it. *)
end end