hop-2012/node.ml

95 lines
2.6 KiB
OCaml
Raw Normal View History

2012-01-08 17:41:04 +00:00
open Printf
open Datastructures
open Status
2012-01-08 17:41:04 +00:00
type handle_message_t = t -> Sexp.t -> unit
and t = {
mutable names: StringSet.t;
class_name: string;
handle_message: handle_message_t
}
let directory = ref StringMap.empty
let local_container_name () = "server"
let make class_name handler = {
names = StringSet.empty;
class_name = class_name;
handle_message = handler
}
let lookup name =
try Some (StringMap.find name !directory)
with Not_found -> None
let exists name = StringMap.mem name !directory
2012-01-08 17:41:04 +00:00
let bind (filter, node) =
if filter = ""
2012-01-08 19:48:07 +00:00
then (Log.warn "Binding to empty name forbidden" []; false)
2012-01-08 17:41:04 +00:00
else
if StringMap.mem filter !directory
then false
else (directory := StringMap.add filter node !directory;
node.names <- StringSet.add filter node.names;
2012-01-08 19:48:07 +00:00
Log.info "Node bound" [Sexp.Str filter; Sexp.Str node.class_name];
2012-01-08 17:41:04 +00:00
true)
(* For use in factory constructor functions, hence the odd return type and values *)
let make_named class_name node_name handler =
let node = make class_name handler in
if bind (node_name, node) then Ok node else Problem (Sexp.Str "bind-failed")
(* For use in factory constructor functions, hence the odd return type and values *)
let make_idempotent_named class_name node_name handler =
match lookup node_name with
| Some n ->
if n.class_name = class_name
then Ok n
else Problem (Sexp.Str "class-mismatch")
| None ->
let node = make class_name handler in
if bind (node_name, node) then Ok node else Problem (Sexp.Str "bind-failed")
2012-01-08 17:41:04 +00:00
let unbind name =
match lookup name with
| Some n ->
2012-01-08 19:48:07 +00:00
Log.info "Node unbound" [Sexp.Str name; Sexp.Str n.class_name];
2012-01-08 17:41:04 +00:00
n.names <- StringSet.remove name n.names;
directory := StringMap.remove name !directory;
true
| None ->
false
let unbind_all n =
StringSet.iter (fun name -> ignore (unbind name)) n.names;
n.names <- StringSet.empty
let send name body =
match lookup name with
| Some n ->
(try n.handle_message n body
with e ->
2012-01-08 19:48:07 +00:00
Log.warn "Node message handler raised exception"
[Sexp.Str name;
Sexp.Str (Printexc.to_string e)]);
true
2012-01-08 17:41:04 +00:00
| None -> false
let post name label body token =
send name (Message.post (label, body, token))
let bind_ignore (filter, node) =
if bind (filter, node)
then ()
2012-01-08 19:48:07 +00:00
else Log.warn "Duplicate binding" [Sexp.Str filter]
2012-01-08 17:41:04 +00:00
let send_ignore name body =
if send name body || name = ""
2012-01-08 17:41:04 +00:00
then ()
else Log.warn "send to missing node" [Sexp.Str name; body]
2012-01-08 17:41:04 +00:00
let post_ignore name label body token =
send_ignore name (Message.post (label, body, token))