aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiacomo Cavalieri <giacomo.cavalieri@icloud.com>2024-01-04 19:13:14 +0100
committerGitHub <noreply@github.com>2024-01-04 18:13:14 +0000
commita38889c285bef95359e36c93da37221126f96556 (patch)
tree33f07bcccc5a2f46e2cda51cac7a86b22885337f
parenta07bba0954e440ccd3eb4d167e1eacb0065cc0af (diff)
downloadlustre-a38889c285bef95359e36c93da37221126f96556.tar.gz
lustre-a38889c285bef95359e36c93da37221126f96556.zip
🔀 Add logging to `lustre/try` (#30)
* :heavy_plus_sign: Add `gleam_community_ansi` dependency * :sparkles: Add log message when server is started * :sparkles: Add retry policy and logging if port is taken
-rw-r--r--gleam.toml1
-rw-r--r--manifest.toml3
-rw-r--r--src/http.ffi.mjs15
-rw-r--r--src/http_ffi.erl34
-rw-r--r--src/lustre/try.gleam29
5 files changed, 74 insertions, 8 deletions
diff --git a/gleam.toml b/gleam.toml
index ea79212..0c4250d 100644
--- a/gleam.toml
+++ b/gleam.toml
@@ -16,3 +16,4 @@ internal_modules = [
[dependencies]
gleam_stdlib = "~> 0.34"
+gleam_community_ansi = "~> 1.3"
diff --git a/manifest.toml b/manifest.toml
index c23fa90..ef7a2b2 100644
--- a/manifest.toml
+++ b/manifest.toml
@@ -2,8 +2,11 @@
# You typically do not need to edit this file
packages = [
+ { name = "gleam_community_ansi", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "AB7C3CCC894653637E02DC455D5890C8CF3064E83E78CFE61145A4C458D02DE6" },
+ { name = "gleam_community_colour", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "A49A5E3AE8B637A5ACBA80ECB9B1AFE89FD3D5351FF6410A42B84F666D40D7D5" },
{ name = "gleam_stdlib", version = "0.34.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "1FB8454D2991E9B4C0C804544D8A9AD0F6184725E20D63C3155F0AEB4230B016" },
]
[requirements]
+gleam_community_ansi = { version = "~> 1.3" }
gleam_stdlib = { version = "~> 0.34" }
diff --git a/src/http.ffi.mjs b/src/http.ffi.mjs
index 06d5b31..3f59933 100644
--- a/src/http.ffi.mjs
+++ b/src/http.ffi.mjs
@@ -85,6 +85,17 @@ const server = Http.createServer((req, res) => {
}
});
-export const serve = (port) => {
- server.listen(port, "localhost");
+export const serve = (host, port, on_start, on_port_taken) => {
+ let tries = 1;
+ server.on("error", (error) => {
+ if (error.code === "EADDRINUSE") {
+ let is_first_try = tries === 1;
+ if (is_first_try) {
+ on_port_taken(port);
+ }
+ tries++;
+ port++;
+ server.listen(port, host);
+ }
+ }).listen(port, host, () => { on_start(port) });
};
diff --git a/src/http_ffi.erl b/src/http_ffi.erl
index 507ee06..5304ee4 100644
--- a/src/http_ffi.erl
+++ b/src/http_ffi.erl
@@ -1,7 +1,7 @@
-module(http_ffi).
--export([serve/1]).
+-export([serve/4]).
-serve(Port) ->
+serve(Host, Port, OnStart, OnPortTaken) ->
{ok, Pattern} = re:compile("name *= *\"(?<Name>.+)\""),
{ok, Toml} = file:read_file("gleam.toml"),
{match, [Name]} = re:run(Toml, Pattern, [{capture, all_names, binary}]),
@@ -43,25 +43,51 @@ serve(Port) ->
inets:start(),
Address = {127, 0, 0, 1},
+ ActualPort =
+ case port_available(Port) of
+ true ->
+ Port;
+ false ->
+ OnPortTaken(Port),
+ first_available_port(Port + 1)
+ end,
+
{ok, Pid} =
httpd:start_service([
{bind_address, Address},
{document_root, AbsPath},
{server_root, AbsPath},
{directory_index, ["index.html"]},
- {server_name, "localhost"},
- {port, Port},
+ {server_name, binary_to_list(Host)},
+ {port, ActualPort},
{default_type, "text/html"},
{mime_types, mime_types()},
{modules, [mod_alias, mod_dir, mod_get]}
]),
+ OnStart(ActualPort),
+
receive
{From, shutdown} ->
ok = httpd:stop_service(Pid),
From ! done
end.
+port_available(Port) ->
+ case gen_tcp:listen(Port, []) of
+ {ok, Sock} ->
+ ok = gen_tcp:close(Sock),
+ true;
+ _ ->
+ false
+ end.
+
+first_available_port(Port) ->
+ case port_available(Port) of
+ true -> Port;
+ false -> first_available_port(Port + 1)
+ end.
+
mime_types() ->
[
{"html", "text/html"},
diff --git a/src/lustre/try.gleam b/src/lustre/try.gleam
index 5984f30..83d6e5a 100644
--- a/src/lustre/try.gleam
+++ b/src/lustre/try.gleam
@@ -1,7 +1,32 @@
+import gleam/int
+import gleam/io
+import gleam_community/ansi
+
pub fn main() {
- serve(1234)
+ let host = "localhost"
+ let port = 1234
+
+ let on_start = fn(actual_port) {
+ let address = "http://" <> host <> ":" <> int.to_string(actual_port)
+ io.println("✨ Server has been started at " <> ansi.bold(address))
+ }
+
+ let on_port_taken = fn(taken_port) {
+ io.println(
+ "🚨 Port "
+ <> ansi.bold(int.to_string(taken_port))
+ <> " already in use, using next available port",
+ )
+ }
+
+ serve(host, port, on_start, on_port_taken)
}
@external(erlang, "http_ffi", "serve")
@external(javascript, "../http.ffi.mjs", "serve")
-fn serve(port: Int) -> Nil
+fn serve(
+ host: String,
+ port: Int,
+ on_start: fn(Int) -> Nil,
+ on_port_taken: fn(Int) -> Nil,
+) -> Nil