hop-2012/server/subscription.ml

99 lines
3.1 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 Datastructures
type t = {
mutable live: bool;
uuid: Uuid.t;
filter: Sexp.t;
sink: Node.name;
2012-01-08 17:41:04 +00:00
name: Sexp.t
}
2012-05-10 19:22:58 +00:00
type creation_t =
| Old of t
| New of t
2012-01-08 17:41:04 +00:00
2012-05-10 19:22:58 +00:00
type set_t = {
mutable subscription_table: Uuid.t SexpMap.t;
mutable uuid_table: t BytesMap.t
2012-05-10 19:22:58 +00:00
}
2012-01-08 17:41:04 +00:00
2012-05-10 19:22:58 +00:00
let new_set () = {
subscription_table = SexpMap.empty;
uuid_table = BytesMap.empty
2012-05-10 19:22:58 +00:00
}
let count subs = SexpMap.cardinal subs.subscription_table
let key_from sink_bs name filter = Sexp.Arr [Sexp.Str sink_bs; name; filter]
2012-05-05 14:30:31 +00:00
let create source subs filter sink_str name reply_sink reply_name =
2012-05-10 19:22:58 +00:00
let key = key_from sink_str name filter in
try
let uuid = SexpMap.find key subs.subscription_table in
lwt () =
Node.post_ignore' reply_sink reply_name (Message.subscribe_ok (Sexp.str uuid)) Sexp.emptystr
2012-05-10 19:22:58 +00:00
in
return (Old (BytesMap.find (Bytes.of_string uuid) subs.uuid_table))
2012-05-10 19:22:58 +00:00
with Not_found ->
let uuid = Uuid.create () in
let sink = Node.name_of_bytes sink_str in
2012-05-10 19:22:58 +00:00
let sub = {
live = true;
uuid = uuid;
filter = filter;
sink = sink;
name = name
} in
subs.uuid_table <- BytesMap.add (Bytes.of_string uuid) sub subs.uuid_table;
2012-05-10 19:22:58 +00:00
subs.subscription_table <- SexpMap.add key uuid subs.subscription_table;
lwt () = Lwt.join [
Meta.announce_subscription source filter sink_str name true;
Node.post_ignore' reply_sink reply_name (Message.subscribe_ok (Sexp.str uuid)) Sexp.emptystr
2012-05-10 19:22:58 +00:00
] in
return (New sub)
2012-01-08 17:41:04 +00:00
2012-03-06 22:05:57 +00:00
let delete source subs uuid =
2012-05-10 19:22:58 +00:00
try
let sub = BytesMap.find uuid subs.uuid_table in
sub.live <- false;
subs.uuid_table <- BytesMap.remove uuid subs.uuid_table;
2012-05-10 19:22:58 +00:00
let key = key_from sub.sink.Node.label sub.name sub.filter in
subs.subscription_table <- SexpMap.remove key subs.subscription_table;
2012-05-05 22:18:23 +00:00
lwt () = Meta.announce_subscription source sub.filter sub.sink.Node.label sub.name false in
return (Some sub)
with Not_found ->
2012-05-05 22:18:23 +00:00
return None
2012-01-08 17:41:04 +00:00
let lookup subs uuid =
try Some (BytesMap.find uuid subs.uuid_table)
with Not_found -> None
2012-03-05 21:56:28 +00:00
let send_to_subscription' sub body delete_action =
2012-01-08 17:41:04 +00:00
if not sub.live
2012-05-05 22:18:23 +00:00
then return false
2012-01-08 17:41:04 +00:00
else
match_lwt Node.post sub.sink sub.name body (Sexp.str sub.uuid) with
2012-05-05 22:18:23 +00:00
| true -> return true
| false -> (lwt _ = delete_action sub.uuid in return false)
2012-03-06 22:05:57 +00:00
let send_to_subscription source subs sub body =
send_to_subscription' sub body (fun (uuid) -> delete source subs (Bytes.of_string uuid))