this repo has no description
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

ls/read/write now work

+161 -55
+1
mvp/ocaml/bellairs_intf.ml
··· 9 9 val delete : dir -> string -> unit 10 10 val size : file -> int64 11 11 val read : ?off:int64 -> ?len:int64 -> file -> string 12 + val write : ?off:int64 -> ?len:int64 -> file -> string -> unit 12 13 end 13 14 14 15 module type Sigs = sig
+78 -28
mvp/ocaml/client/client.ml
··· 31 31 let results = Capability.call_for_value_exn t method_id request in 32 32 match Results.file_get results with 33 33 | Some file -> file 34 - | None -> failwith "create: no file returned" 34 + | None -> failwith "Storage.create: no file returned" 35 35 36 36 let open_ t name = 37 37 let open API.Client.Directory.Open in 38 38 let request, params = Capability.Request.create Params.init_pointer in 39 39 Params.name_set params name; 40 - let results = Capability.call_for_value_exn t method_id request in 41 - match Results.file_get results with 42 - | Some file -> file 43 - | None -> failwith "open: no file returned" 40 + Capability.call_for_caps t method_id request Results.file_get_pipelined 44 41 45 42 let delete t name = 46 43 let open API.Client.Directory.Delete in ··· 70 67 in 71 68 let results = Capability.call_for_value_exn t method_id request in 72 69 Results.data_get results 70 + 71 + let write ?off ?len t d = 72 + let open API.Client.File.Write in 73 + let request, params = Capability.Request.create Params.init_pointer in 74 + let () = 75 + match off with 76 + | None -> () 77 + | Some off -> Params.off_set params (Stdint.Int64.to_uint64 off) 78 + in 79 + let () = 80 + match len with 81 + | None -> () 82 + | Some len -> Params.len_set params (Stdint.Int64.to_uint64 len) 83 + in 84 + Params.data_set params d; 85 + Capability.call_for_unit_exn t method_id request 73 86 end 74 87 75 88 let connect net uri f = ··· 81 94 let pp_name ppf name = Fmt.pf ppf "%a" Fmt.(styled `Bold string) name 82 95 let pp_entry ppf entry = pp_name ppf entry.Storage.name 83 96 84 - let ls net uri = 97 + let ls net () uri = 85 98 connect net uri @@ fun dir -> 86 99 let entries = Storage.list dir in 87 - Printf.printf "total %d:\n" (List.length entries); 100 + Fmt.pr "total %d:\n" (List.length entries); 88 101 List.iter (Fmt.pr "- %a\n" pp_entry) entries; 89 102 Fmt.pr "%!" 90 103 91 - let create net uri name = 104 + let create net () uri name data = 92 105 connect net uri @@ fun dir -> 93 - let _file = Storage.create dir name in 94 - Fmt.pr "Created file '%a'\n" pp_name name 106 + let file = Storage.create dir name in 107 + Storage.write file data; 108 + Fmt.pr "%a is created.\n%!" pp_name name 95 109 96 - let open_file net uri name = 110 + let open_file net () uri name = 97 111 connect net uri @@ fun dir -> 98 112 let _file = Storage.open_ dir name in 99 - Fmt.pr "Opened file <raw>\n" 113 + Fmt.pr "%a: <raw>.\n%!" pp_name name 100 114 101 - let delete net uri name = 115 + let delete net () uri name = 102 116 connect net uri @@ fun dir -> 103 117 Storage.delete dir name; 104 - Fmt.pr "Deleted file '%a'\n" pp_name name 118 + Fmt.pr "%a is deleted.\n%!" pp_name name 105 119 106 - let size net uri name = 120 + let size net () uri name = 107 121 connect net uri @@ fun dir -> 108 122 let file = Storage.open_ dir name in 109 123 let size = Storage.size file in 110 - Fmt.pr "Size of '%s': %Ld bytes\n" name size 124 + Fmt.pr "%a: %Ld bytes.\n%!" pp_name name size 111 125 112 - let read net addr name offset length = 113 - connect net addr @@ fun dir -> 114 - let file = Storage.open_ dir name in 126 + let read net () uri name offset length = 127 + connect net uri @@ fun dir -> 128 + Capability.with_ref (Storage.open_ dir name) @@ fun file -> 115 129 let data = Storage.read ?off:offset ?len:length file in 116 - Printf.printf "Contents of '%s':\n%s\n" name data 130 + Fmt.pr "%a: %S\n%!" pp_name name data 131 + 132 + let write net () uri name offset length data = 133 + connect net uri @@ fun dir -> 134 + Capability.with_ref (Storage.open_ dir name) @@ fun file -> 135 + Storage.write ?off:offset ?len:length file data; 136 + Fmt.pr "%d bytes successfully written into %a.\n%!" (String.length data) 137 + pp_name name 117 138 118 139 open Cmdliner 119 140 ··· 122 143 Logs.set_reporter (Logs_fmt.reporter ()) 123 144 124 145 let connect_addr = 125 - let i = Arg.info [] ~docv:"ADDR" ~doc:"Address of server (capnp://...)" in 126 - Arg.(required @@ pos 0 (some Capnp_rpc_unix.sturdy_uri) None i) 146 + let env = Cmd.Env.info "BELLAIRS_CAP" in 147 + let i = 148 + Arg.info ~env [ "cap" ] ~docv:"CAP" ~doc:"capabilities file(capnp://...)" 149 + in 150 + Arg.(required @@ opt (some Capnp_rpc_unix.sturdy_uri) None i) 127 151 128 152 let name_arg = 129 153 let i = Arg.info [] ~docv:"NAME" ~doc:"Name of the file" in 154 + Arg.(required @@ pos 0 (some string) None i) 155 + 156 + let data_arg = 157 + let i = Arg.info [] ~docv:"DATA" ~doc:"Data of the file" in 130 158 Arg.(required @@ pos 1 (some string) None i) 131 159 132 160 let offset_arg = ··· 143 171 in 144 172 Arg.(value @@ opt (some int64) None i) 145 173 174 + let setup_log style_renderer level = 175 + Fmt_tty.setup_std_outputs ?style_renderer (); 176 + Logs.set_level level; 177 + Logs.set_reporter (Logs_fmt.reporter ()); 178 + () 179 + 180 + let setup_log = 181 + Term.(const setup_log $ Fmt_cli.style_renderer () $ Logs_cli.level ()) 182 + 146 183 let ls_cmd env = 147 184 let doc = "List files in the directory" in 148 185 let info = Cmd.info "ls" ~doc in 149 - Cmd.v info Term.(const (ls env#net) $ connect_addr) 186 + Cmd.v info Term.(const (ls env#net) $ setup_log $ connect_addr) 150 187 151 188 let create_cmd env = 152 189 let doc = "Create a new file" in 153 190 let info = Cmd.info "create" ~doc in 154 - Cmd.v info Term.(const (create env#net) $ connect_addr $ name_arg) 191 + Cmd.v info 192 + Term.( 193 + const (create env#net) $ setup_log $ connect_addr $ name_arg $ data_arg) 155 194 156 195 let open_cmd env = 157 196 let doc = "Open an existing file and show its ID" in 158 197 let info = Cmd.info "open" ~doc in 159 - Cmd.v info Term.(const (open_file env#net) $ connect_addr $ name_arg) 198 + Cmd.v info 199 + Term.(const (open_file env#net) $ setup_log $ connect_addr $ name_arg) 160 200 161 201 let delete_cmd env = 162 202 let doc = "Delete a file" in 163 203 let info = Cmd.info "delete" ~doc in 164 - Cmd.v info Term.(const (delete env#net) $ connect_addr $ name_arg) 204 + Cmd.v info Term.(const (delete env#net) $ setup_log $ connect_addr $ name_arg) 165 205 166 206 let size_cmd env = 167 207 let doc = "Get the size of a file" in 168 208 let info = Cmd.info "size" ~doc in 169 - Cmd.v info Term.(const (size env#net) $ connect_addr $ name_arg) 209 + Cmd.v info Term.(const (size env#net) $ setup_log $ connect_addr $ name_arg) 170 210 171 211 let read_cmd env = 172 212 let doc = "Read the contents of a file" in 173 213 let info = Cmd.info "read" ~doc in 174 214 Cmd.v info 175 215 Term.( 176 - const (read env#net) $ connect_addr $ name_arg $ offset_arg $ length_arg) 216 + const (read env#net) 217 + $ setup_log $ connect_addr $ name_arg $ offset_arg $ length_arg) 218 + 219 + let write_cmd env = 220 + let doc = "Write some contents to a file" in 221 + let info = Cmd.info "write" ~doc in 222 + Cmd.v info 223 + Term.( 224 + const (write env#net) 225 + $ setup_log $ connect_addr $ name_arg $ offset_arg $ length_arg $ data_arg) 177 226 178 227 let main_cmd env = 179 228 let doc = "Bellairs Storage Client" in ··· 186 235 delete_cmd env; 187 236 size_cmd env; 188 237 read_cmd env; 238 + write_cmd env; 189 239 ] 190 240 191 241 let () = exit @@ Eio_main.run @@ fun env -> Cmd.eval (main_cmd env)
+9 -1
mvp/ocaml/client/dune
··· 1 1 (executables 2 2 (names client) 3 - (libraries bellairs eio_main capnp-rpc logs.fmt capnp-rpc-unix)) 3 + (libraries 4 + bellairs 5 + eio_main 6 + capnp-rpc 7 + logs.fmt 8 + capnp-rpc-unix 9 + fmt.cli 10 + logs.cli 11 + fmt.tty))
+7 -7
mvp/ocaml/server/directory.ml
··· 11 11 let open Directory.Create in 12 12 let name = Params.name_get params in 13 13 release_param_caps (); 14 - let response, results = Service.Response.create Results.init_pointer in 15 14 let file = Impl.create dir name in 16 15 let file_cap = File.local file in 17 - (* TODO: add persistence *) 16 + let response, results = Service.Response.create Results.init_pointer in 18 17 Results.file_set results (Some file_cap); 18 + Capability.dec_ref file_cap; 19 19 Service.return response 20 20 21 21 method list_impl _ release_param_caps = ··· 29 29 List.iteri 30 30 (fun i e -> 31 31 let entry = Capnp.Array.get entries_array i in 32 + let file = File.local e.Impl.file in 32 33 API.Builder.Directory.Entry.name_set entry e.Impl.name; 33 - API.Builder.Directory.Entry.file_set entry 34 - (Some (File.local e.Impl.file))) 34 + API.Builder.Directory.Entry.file_set entry (Some file)) 35 35 entries; 36 36 Service.return response 37 37 38 - method open_impl params release_param_caps = 38 + method open_impl params _release_param_caps = 39 39 let open Directory.Open in 40 40 let name = Params.name_get params in 41 - release_param_caps (); 42 41 let response, results = Service.Response.create Results.init_pointer in 43 42 try 44 43 let file = Impl.open_ dir name in 45 - Results.file_set results (Some (File.local file)); 44 + let file_cap = File.local file in 45 + Results.file_set results (Some file_cap); 46 46 Service.return response 47 47 with Not_found -> Service.fail "File '%s' not found" name 48 48
+9 -1
mvp/ocaml/server/dune
··· 1 1 (executable 2 2 (name server) 3 - (libraries bellairs eio_main capnp-rpc logs.fmt capnp-rpc-unix)) 3 + (libraries 4 + bellairs 5 + eio_main 6 + capnp-rpc 7 + logs.fmt 8 + fmt.cli 9 + logs.cli 10 + fmt.tty 11 + capnp-rpc-unix))
+16 -3
mvp/ocaml/server/file.ml
··· 1 1 open Capnp_rpc.Std 2 2 3 + let int64_of_uint64 n = 4 + match Stdint.Int64.of_uint64 n with -1L -> None | i -> Some i 5 + 3 6 let local file = 4 7 let module File = API.Service.File in 5 8 File.local ··· 8 11 9 12 method read_impl params release_param_caps = 10 13 let open File.Read in 11 - let off = Stdint.Int64.of_uint64 (Params.off_get params) in 12 - let len = Stdint.Int64.of_uint64 (Params.len_get params) in 14 + let off = int64_of_uint64 (Params.off_get params) in 15 + let len = int64_of_uint64 (Params.len_get params) in 13 16 release_param_caps (); 14 17 let response, results = Service.Response.create Results.init_pointer in 15 - let data = Impl.read file ~off ~len in 18 + let data = Impl.read file ?off ?len in 16 19 Results.data_set results data; 20 + Service.return response 21 + 22 + method write_impl params release_param_caps = 23 + let open File.Write in 24 + let off = int64_of_uint64 (Params.off_get params) in 25 + let len = int64_of_uint64 (Params.len_get params) in 26 + let data = Params.data_get params in 27 + release_param_caps (); 28 + let response = Service.Response.create_empty () in 29 + Impl.write file ?off ?len data; 17 30 Service.return response 18 31 19 32 method size_impl _ release_param_caps =
+23 -6
mvp/ocaml/server/impl.ml
··· 1 1 (* TODO: put the real implementation here -- for now it's just an 2 2 in-memory database *) 3 3 4 - type file = { content : string; size : int64 } 4 + type file = { mutable content : string } 5 5 type dir = (string, file) Hashtbl.t 6 6 type entry = { name : string; file : file } 7 7 8 8 let create files name = 9 - let file = { content = ""; size = 0L } in 9 + let file = { content = "" } in 10 10 Hashtbl.add files name file; 11 11 file 12 12 ··· 19 19 let open_ (files : dir) name = Hashtbl.find files name 20 20 let delete files name = Hashtbl.remove files name 21 21 22 - let read ?(off = 0L) ?(len = Int64.max_int) file = 22 + let read ?(off = 0L) ?len file = 23 23 let content_len = String.length file.content in 24 24 let off = Int64.to_int off in 25 - let len = Int64.to_int len in 26 - let off = max 0 (min off content_len) in 25 + let len = 26 + match len with None -> content_len | Some len -> Int64.to_int len 27 + in 27 28 let max_len = content_len - off in 28 29 let len = if len >= max_len then max_len else len in 29 30 String.sub file.content off len 30 31 31 - let size file = file.size 32 + let write ?(off = 0L) ?len file data = 33 + let data_len = String.length data in 34 + let off = Int64.to_int off in 35 + let len = match len with None -> data_len | Some len -> Int64.to_int len in 36 + let required_len = off + len in 37 + let file_content = 38 + if required_len > String.length file.content then ( 39 + let new_content = Bytes.make required_len '\000' in 40 + String.blit file.content 0 new_content 0 (String.length file.content); 41 + let new_content = Bytes.unsafe_to_string new_content in 42 + file.content <- new_content; 43 + new_content) 44 + else file.content 45 + in 46 + String.blit data 0 (Bytes.unsafe_of_string file_content) off len 47 + 48 + let size file = Int64.of_int (String.length file.content) 32 49 33 50 let list files = 34 51 Hashtbl.fold (fun name file acc -> { name; file } :: acc) files []
+12 -6
mvp/ocaml/server/server.ml
··· 3 3 4 4 let cap_file = "storage.cap" 5 5 6 - let serve config = 6 + let serve () config = 7 7 Switch.run @@ fun sw -> 8 8 let root_id = Capnp_rpc_unix.Vat_config.derived_id config "root" in 9 - let restore = Restorer.single root_id (Directory.local (Impl.root ())) in 9 + let root = Impl.root () in 10 + let restore = Restorer.single root_id (Directory.local root) in 10 11 let vat = Capnp_rpc_unix.serve ~sw ~restore config in 11 12 match Capnp_rpc_unix.Cap_file.save_service vat root_id cap_file with 12 13 | Error (`Msg m) -> failwith m ··· 16 17 17 18 open Cmdliner 18 19 19 - let () = 20 - Logs.set_level (Some Logs.Warning); 21 - Logs.set_reporter (Logs_fmt.reporter ()) 20 + let setup_log style_renderer level = 21 + Fmt_tty.setup_std_outputs ?style_renderer (); 22 + Logs.set_level level; 23 + Logs.set_reporter (Logs_fmt.reporter ()); 24 + () 25 + 26 + let setup_log = 27 + Term.(const setup_log $ Fmt_cli.style_renderer () $ Logs_cli.level ()) 22 28 23 29 let serve_cmd env = 24 30 let doc = "run the server" in 25 31 let info = Cmd.info "serve" ~doc in 26 - Cmd.v info Term.(const serve $ Capnp_rpc_unix.Vat_config.cmd env) 32 + Cmd.v info Term.(const serve $ setup_log $ Capnp_rpc_unix.Vat_config.cmd env) 27 33 28 34 let () = exit @@ Eio_main.run @@ fun env -> Cmd.eval (serve_cmd env)
+6 -3
mvp/schema/storage.capnp
··· 2 2 3 3 interface Directory { 4 4 # Represents a directory in the filesystem 5 - 5 + 6 6 list @0 () -> (entries :List(Entry)); 7 7 # Lists all entries in the directory 8 8 ··· 23 23 24 24 interface File { 25 25 # Represents a file in the filesystem 26 - 26 + 27 27 size @0 () -> (size :UInt64); 28 28 # Returns the size of the file in bytes 29 29 30 30 read @1 (off :UInt64 = 0, len :UInt64 = 0xffffffffffffffff) -> (data :Data); 31 31 # Reads data from the file, optionally starting at offset and reading up to len bytes 32 32 # Default is to read the entire file 33 + 34 + write @2 (off :UInt64 = 0, len :UInt64 = 0xffffffffffffffff, data :Data) -> (); 35 + # Write data to the file, optionally starting at offset and reading up to len bytes 36 + # Default is to write the entire file 33 37 } 34 -