Client: add method with_lock to wallet

This commit is contained in:
Mathias 2018-05-22 15:07:42 +02:00 committed by Grégoire Henry
parent c46e731031
commit abc7b7338c
3 changed files with 57 additions and 30 deletions

View File

@ -49,6 +49,7 @@ class simple_printer log =
end end
class type wallet = object class type wallet = object
method with_lock : ( unit -> 'a Lwt.t) -> 'a Lwt.t
method load : string -> default:'a -> 'a Data_encoding.encoding -> 'a tzresult Lwt.t method load : string -> default:'a -> 'a Data_encoding.encoding -> 'a tzresult Lwt.t
method write : string -> 'a -> 'a Data_encoding.encoding -> unit tzresult Lwt.t method write : string -> 'a -> 'a Data_encoding.encoding -> unit tzresult Lwt.t
end end
@ -95,6 +96,7 @@ class proxy_context (obj : full) = object
'p -> 'q -> 'i -> (unit -> unit) tzresult Lwt.t = obj#call_streamed_service 'p -> 'q -> 'i -> (unit -> unit) tzresult Lwt.t = obj#call_streamed_service
method error : type a b. (a, b) lwt_format -> a = obj#error method error : type a b. (a, b) lwt_format -> a = obj#error
method generic_json_call = obj#generic_json_call method generic_json_call = obj#generic_json_call
method with_lock : type a. ( unit -> a Lwt.t) -> a Lwt.t = obj#with_lock
method load : type a. string -> default:a -> a Data_encoding.encoding -> a tzresult Lwt.t = obj#load method load : type a. string -> default:a -> a Data_encoding.encoding -> a tzresult Lwt.t = obj#load
method log : type a. string -> (a, unit) lwt_format -> a = obj#log method log : type a. string -> (a, unit) lwt_format -> a = obj#log
method message : type a. (a, unit) lwt_format -> a = obj#message method message : type a. (a, unit) lwt_format -> a = obj#message

View File

@ -29,6 +29,7 @@ class type io = object
end end
class type wallet = object class type wallet = object
method with_lock : ( unit -> 'a Lwt.t) -> 'a Lwt.t
method load : string -> default:'a -> 'a Data_encoding.encoding -> 'a tzresult Lwt.t method load : string -> default:'a -> 'a Data_encoding.encoding -> 'a tzresult Lwt.t
method write : string -> 'a -> 'a Data_encoding.encoding -> unit tzresult Lwt.t method write : string -> 'a -> 'a Data_encoding.encoding -> unit tzresult Lwt.t
end end

View File

@ -10,11 +10,35 @@
open Client_context open Client_context
class unix_wallet ~base_dir : wallet = object (self) class unix_wallet ~base_dir : wallet = object (self)
method private filename alias_name = method private filename alias_name =
Filename.concat Filename.concat
base_dir base_dir
(Str.(global_replace (regexp_string " ") "_" alias_name) ^ "s") (Str.(global_replace (regexp_string " ") "_" alias_name) ^ "s")
method with_lock : type a. ( unit -> a Lwt.t) -> a Lwt.t =
(fun f ->
let unlock fd =
let fd = Lwt_unix.unix_file_descr fd in
Unix.lockf fd Unix.F_ULOCK 0;
Unix.close fd
in
let lock () =
Lwt_unix.openfile (Filename.concat base_dir "wallet_lock")
Lwt_unix.[O_CREAT; O_WRONLY] 0o644 >>= fun fd ->
Lwt_unix.lockf fd Unix.F_LOCK 0 >>= fun () ->
Lwt.return (fd,(Lwt_unix.on_signal Sys.sigint
(fun _s ->
unlock fd;
exit 0 (* exit code? *) )))
in
lock () >>= fun (fd,sh) ->
(* catch might be useless if f always uses the error monad *)
Lwt.catch f (function e -> Lwt.return (unlock fd; raise e)) >>= fun res ->
Lwt.return (unlock fd) >>= fun () ->
Lwt_unix.disable_signal_handler sh;
Lwt.return res)
method load : type a. string -> default:a -> a Data_encoding.encoding -> a tzresult Lwt.t = method load : type a. string -> default:a -> a Data_encoding.encoding -> a tzresult Lwt.t =
fun alias_name ~default encoding -> fun alias_name ~default encoding ->
let filename = self#filename alias_name in let filename = self#filename alias_name in
@ -23,10 +47,10 @@ class unix_wallet ~base_dir : wallet = object (self)
else else
Lwt_utils_unix.Json.read_file filename Lwt_utils_unix.Json.read_file filename
|> generic_trace |> generic_trace
"couldn't to read the %s file" alias_name >>=? fun json -> "could not read the %s alias file" alias_name >>=? fun json ->
match Data_encoding.Json.destruct encoding json with match Data_encoding.Json.destruct encoding json with
| exception _ -> (* TODO print_error *) | exception _ -> (* TODO print_error *)
failwith "didn't understand the %s file" alias_name failwith "did not understand the %s alias file" alias_name
| data -> | data ->
return data return data