Skip to content

Instantly share code, notes, and snippets.

@tcoopman

tcoopman/App.re Secret

Created March 20, 2020 10:25
Show Gist options
  • Save tcoopman/aa6727cef26fa8b734a150ae62c6fe74 to your computer and use it in GitHub Desktop.
Save tcoopman/aa6727cef26fa8b734a150ae62c6fe74 to your computer and use it in GitHub Desktop.
reweb cache issues
open ReWeb;
let getFile = (path, _request) =>
path |> String.concat("/") |> Response.of_file;
let timeout = 0.25;
let socket = (cache, name, _) => {
let%lwt topic = Context.create(cache, Context.Key(name));
let%lwt subscription = Topic.subscribe(topic);
let rec handler = (pull, push) => {
let incoming = pull(timeout);
let outgoing = Topic.pull(subscription, ~timeout);
let%lwt incoming = incoming;
let%lwt outgoing = outgoing;
Option.iter(push, outgoing);
let%lwt () =
Option.fold(
~none=Lwt.return_unit,
~some=msg => Topic.publish(topic, ~msg),
incoming,
);
handler(pull, push);
};
handler |> Response.of_websocket |> Lwt.return;
};
let max_age = 30 * 24 * 60 * 60;
let cache : Context.cache = Context.Cache.make();
let server =
fun
// [GET /]
| (`GET, [""]) => getFile(["dist", "index.html"])
// [GET /ws]
| (`GET, ["ws", name]) => socket(cache, name)
/* [GET /dist/...] - caches response to any request to /dist/... for a
month, with Webpack-hashed asset file names (i.e. revving) to bust
cache! */
| (`GET, ["dist", ..._] as path) =>
Filter.cache_control(Header.CacheControl.public(~max_age, ())) @@
getFile(path)
| _ => (_ => `Not_found |> Response.of_status |> Lwt.return);
let () = Server.serve(server);
open ReWeb
type key = Key of string
module Cache = Cache.Ephemeral (struct
type t = key
let equal (Key k1) (Key k2) = k1 = k2
let hash = Hashtbl.seeded_hash
end)
type topic = string Topic.t
type cache = topic Cache.t
let create cache name =
let%lwt value = Cache.find_opt cache ~key:name in
let%lwt topic =
match value with
| None ->
Stdlib.print_endline "CREATING A TOPIC" ;
let topic = Topic.make () in
let%lwt () = Cache.add cache ~key:name topic in
topic |> Lwt.return
| Some topic ->
Stdlib.print_endline "FOUND A TOPIC" ;
topic |> Lwt.return
in
Lwt.return topic
let socket = new WebSocket("ws://localhost:8080/ws/foo");
socket.onopen = function(e) {
console.log("[open] Connection established");
console.log("Sending to server");
socket.send("My name is John");
};
socket.onmessage = function(event) {
console.log(`[message] Data received from server: ${event.data}`);
};
socket.onclose = function(event) {
if (event.wasClean) {
console.log(
`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`
);
} else {
// e.g. server process killed or network down
// event.code is usually 1006 in this case
console.log("[close] Connection died");
}
};
socket.onerror = function(error) {
console.log(`[error] ${error.message}`);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment