hop-2012/server/factory.ml

68 lines
2.4 KiB
OCaml
Raw Normal View History

2012-03-07 18:23:41 +00:00
(* Copyright 2012 Tony Garnock-Jones <tonygarnockjones@gmail.com>. *)
2012-05-01 21:36:38 +00:00
(* This file is part of Hop. *)
2012-03-07 18:23:41 +00:00
2012-05-01 21:36:38 +00:00
(* Hop is free software: you can redistribute it and/or modify it *)
2012-03-07 18:23:41 +00:00
(* under the terms of the GNU General Public License as published by the *)
(* Free Software Foundation, either version 3 of the License, or (at your *)
(* option) any later version. *)
2012-05-01 21:36:38 +00:00
(* Hop is distributed in the hope that it will be useful, but *)
2012-03-07 18:23:41 +00:00
(* WITHOUT ANY WARRANTY; without even the implied warranty of *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *)
(* General Public License for more details. *)
(* You should have received a copy of the GNU General Public License *)
2012-05-01 21:36:38 +00:00
(* along with Hop. If not, see <http://www.gnu.org/licenses/>. *)
2012-03-07 18:23:41 +00:00
2012-05-05 22:18:23 +00:00
open Lwt
2012-01-08 17:41:04 +00:00
open Printf
open Sexp
open Datastructures
2012-05-05 22:18:23 +00:00
type factory_t = Sexp.t -> (Sexp.t, Sexp.t) Status.t Lwt.t
2012-01-08 17:41:04 +00:00
let classes = ref BytesMap.empty
2012-01-08 17:41:04 +00:00
let register_class name factory =
if BytesMap.mem name !classes
2012-05-05 22:18:23 +00:00
then (ignore (Log.error "Duplicate node class name" [Str name]);
Server_control.shutdown_now [litstr "Duplicate node class name"; Str name];
2012-05-05 22:18:23 +00:00
Lwt_unix.yield ())
else (ignore (Log.info "Registered node class" [Str name]);
classes := BytesMap.add name factory !classes;
2012-05-05 22:18:23 +00:00
return ())
2012-01-08 17:41:04 +00:00
2012-04-29 23:41:28 +00:00
let all_class_names () =
Datastructures.bytes_map_keys !classes
2012-04-29 23:41:28 +00:00
2012-01-08 17:41:04 +00:00
let lookup_class name =
try Some (BytesMap.find name !classes)
2012-01-08 17:41:04 +00:00
with Not_found -> None
let factory_handler n sexp =
match Message.message_of_sexp sexp with
| Message.Create (Str classname, arg, Str reply_sink, Str reply_name) ->
2012-05-05 22:18:23 +00:00
lwt reply =
match lookup_class classname with
2012-05-05 22:18:23 +00:00
| Some factory ->
(match_lwt factory arg with
| Status.Ok info ->
ignore (Log.info "Node create ok"
[Str classname; arg; Str reply_sink; Str reply_name; info]);
return (Message.create_ok info)
| Status.Problem explanation ->
ignore (Log.info "Node create failed"
[Str classname; arg; Str reply_sink; Str reply_name; explanation]);
return (Message.create_failed (Arr [litstr "constructor"; explanation])))
2012-05-05 22:18:23 +00:00
| None ->
ignore (Log.warn "Node class not found" [Str classname]);
return (Message.create_failed (Arr [litstr "factory"; litstr "class-not-found"]))
in
Node.post_ignore' reply_sink (Str reply_name) reply emptystr
2012-01-08 17:41:04 +00:00
| m ->
Util.message_not_understood "factory" m
let init () =
Node.bind_ignore (Node.name_of_bytes (Bytes.of_string "factory"), Node.make (Bytes.of_string "factory") factory_handler)