Skip to content

Commit

Permalink
add supervisor for clock and pool; big test refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
rawhat committed Mar 23, 2024
1 parent 5c28b23 commit 4dcb6d5
Show file tree
Hide file tree
Showing 10 changed files with 272 additions and 101 deletions.
2 changes: 1 addition & 1 deletion examples/complete/manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ packages = [
{ name = "glisten", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib"], otp_app = "glisten", source = "hex", outer_checksum = "BF6C557531E85B13518F3CEA611843C003294C45101D530D1F0DBB0200D51C03" },
{ name = "hpack_erl", version = "0.3.0", build_tools = ["rebar3"], requirements = [], otp_app = "hpack", source = "hex", outer_checksum = "D6137D7079169D8C485C6962DFE261AF5B9EF60FBC557344511C1E65E3D95FB0" },
{ name = "logging", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "logging", source = "hex", outer_checksum = "82C112ED9B6C30C1772A6FE2613B94B13F62EA35F5869A2630D13948D297BD39" },
{ name = "mist", version = "1.0.0-rc2", build_tools = ["gleam"], requirements = ["birl", "gleam_erlang", "gleam_http", "gleam_otp", "gleam_stdlib", "glisten", "hpack_erl", "logging"], source = "local", path = "../.." },
{ name = "mist", version = "1.0.0-rc3", build_tools = ["gleam"], requirements = ["birl", "gleam_erlang", "gleam_http", "gleam_otp", "gleam_stdlib", "glisten", "hpack_erl", "logging"], source = "local", path = "../.." },
{ name = "ranger", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "ranger", source = "hex", outer_checksum = "28E615AE7590ED922AF1510DDF606A2ECBBC2A9609AF36D412EDC925F06DFD20" },
]

Expand Down
10 changes: 10 additions & 0 deletions examples/complete/src/complete.gleam
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import gleam/bytes_builder
import gleam/dict.{type Dict}
import gleam/erlang/atom.{type Atom}
import gleam/erlang/process
import gleam/http/request.{type Request}
import gleam/http/response.{type Response}
Expand All @@ -10,7 +12,15 @@ import gleam/result
import gleam/string
import mist.{type Connection, type ResponseData}

@external(erlang, "logger", "update_primary_config")
fn logger_update_primary_config(config: Dict(Atom, Atom)) -> Result(Nil, any)

pub fn main() {
logger_update_primary_config(
dict.from_list([
#(atom.create_from_string("level"), atom.create_from_string("debug")),
]),
)
// These values are for the Websocket process initialized below
let selector = process.new_selector()
let state = Nil
Expand Down
2 changes: 1 addition & 1 deletion gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ gleam_stdlib = "~> 0.35 or ~> 1.0"
gleam_erlang = "~> 0.24"
gleam_http = "~> 3.5"
gleam_otp = "~> 0.9"
glisten = "~> 1.0"
hpack_erl = "~> 0.3"
birl = "~> 1.3"
logging = "~> 1.0"
glisten = "~> 1.0"

[dev-dependencies]
gleeunit = "~> 1.0"
Expand Down
8 changes: 4 additions & 4 deletions manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# You typically do not need to edit this file

packages = [
{ name = "birl", version = "1.5.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "23BFE5AB0D7D9E4ECC5BB89B7ABDDF8E976D98C65D2E173D116E6AAFBF24E633" },
{ name = "birl", version = "1.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "0757CFE97DA52F19BC3262AC3DD284D9DAD2718D4C1830888DE483FB147477D4" },
{ name = "certifi", version = "2.12.0", build_tools = ["rebar3"], requirements = [], otp_app = "certifi", source = "hex", outer_checksum = "EE68D85DF22E554040CDB4BE100F33873AC6051387BAF6A8F6CE82272340FF1C" },
{ name = "gleam_erlang", version = "0.24.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "26BDB52E61889F56A291CB34167315780EE4AA20961917314446542C90D1C1A0" },
{ name = "gleam_erlang", version = "0.25.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "054D571A7092D2A9727B3E5D183B7507DAB0DA41556EC9133606F09C15497373" },
{ name = "gleam_hackney", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_stdlib", "hackney"], otp_app = "gleam_hackney", source = "hex", outer_checksum = "066B1A55D37DBD61CC72A1C4EDE43C6015B1797FAF3818C16FE476534C7B6505" },
{ name = "gleam_http", version = "3.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "8C07DF9DF8CC7F054C650839A51C30A7D3C26482AC241C899C1CEA86B22DBE51" },
{ name = "gleam_otp", version = "0.10.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "0B04FE915ACECE539B317F9652CAADBBC0F000184D586AAAF2D94C100945D72B" },
Expand All @@ -31,6 +31,6 @@ gleam_http = { version = "~> 3.5" }
gleam_otp = { version = "~> 0.9" }
gleam_stdlib = { version = "~> 0.35 or ~> 1.0" }
gleeunit = { version = "~> 1.0" }
glisten = { version = "~> 1.0" }
glisten = { version = "~> 1.0"}
hpack_erl = { version = "~> 0.3" }
logging = { version = "~> 1.0"}
logging = { version = "~> 1.0" }
84 changes: 69 additions & 15 deletions src/mist.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import gleam/option.{type Option, None, Some}
import gleam/otp/actor
import gleam/otp/supervisor
import gleam/result
import gleam/string
import gleam/string_builder.{type StringBuilder}
import glisten
import glisten/transport
import mist/internal/buffer.{type Buffer, Buffer}
import mist/internal/clock
import mist/internal/encoder
import mist/internal/file
import mist/internal/handler
Expand Down Expand Up @@ -357,17 +359,51 @@ fn convert_body_types(
response.set_body(resp, new_body)
}

fn convert_glisten_error(err: glisten.StartError) -> actor.StartError {
case err {
glisten.AcceptorTimeout -> actor.InitTimeout
glisten.AcceptorFailed(reason) -> actor.InitFailed(reason)
glisten.AcceptorCrashed(reason) -> actor.InitCrashed(reason)
glisten.ListenerClosed ->
actor.InitFailed(process.Abnormal("Listener socket closed"))
glisten.ListenerTimeout ->
actor.InitFailed(process.Abnormal("Listener startup timed out"))
glisten.SystemError(reason) ->
actor.InitFailed(process.Abnormal(
"Socket error: " <> string.inspect(reason),
))
}
}

/// Start a `mist` service over HTTP with the provided builder.
pub fn start_http(
builder: Builder(Connection, ResponseData),
) -> Result(Subject(supervisor.Message), glisten.StartError) {
fn(req) { convert_body_types(builder.handler(req)) }
|> handler.with_func
|> glisten.handler(handler.init, _)
|> glisten.serve(builder.port)
|> result.map(fn(subj) {
builder.after_start(builder.port, Http)
subj
let clock = supervisor.worker(fn(_argument) { clock.start() })
let glisten_pool =
supervisor.supervisor(fn(_argument) {
fn(req) { convert_body_types(builder.handler(req)) }
|> handler.with_func
|> glisten.handler(handler.init, _)
|> glisten.serve(builder.port)
|> result.map(fn(subj) {
builder.after_start(builder.port, Http)
subj
})
|> result.map_error(convert_glisten_error)
})

supervisor.start(fn(children) {
children
|> supervisor.add(clock)
|> supervisor.add(glisten_pool)
})
|> result.map_error(fn(err) {
case err {
actor.InitTimeout -> glisten.AcceptorTimeout
actor.InitFailed(reason) -> glisten.AcceptorFailed(reason)
actor.InitCrashed(reason) -> glisten.AcceptorCrashed(reason)
}
})
}

Expand Down Expand Up @@ -407,15 +443,33 @@ pub fn start_https(

use _ <- result.then(res)

fn(req) { convert_body_types(builder.handler(req)) }
|> handler.with_func
|> glisten.handler(handler.init, _)
|> glisten.serve_ssl(builder.port, certfile, keyfile)
|> result.map_error(GlistenError)
|> result.map(fn(subj) {
builder.after_start(builder.port, Https)
subj
let clock = supervisor.worker(fn(_argument) { clock.start() })

let glisten_pool =
supervisor.supervisor(fn(_argument) {
fn(req) { convert_body_types(builder.handler(req)) }
|> handler.with_func
|> glisten.handler(handler.init, _)
|> glisten.serve_ssl(builder.port, certfile, keyfile)
|> result.map(fn(subj) {
builder.after_start(builder.port, Https)
subj
})
|> result.map_error(convert_glisten_error)
})
supervisor.start(fn(children) {
children
|> supervisor.add(clock)
|> supervisor.add(glisten_pool)
})
|> result.map_error(fn(err) {
case err {
actor.InitTimeout -> glisten.AcceptorTimeout
actor.InitFailed(reason) -> glisten.AcceptorFailed(reason)
actor.InitCrashed(reason) -> glisten.AcceptorCrashed(reason)
}
})
|> result.map_error(GlistenError)
}

/// These are the types of messages that a websocket handler may receive.
Expand Down
2 changes: 1 addition & 1 deletion src/mist/internal/clock.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn get_date() -> String {
case ets_lookup_element(MistClock, DateHeader, 2) {
Ok(value) -> value
_ -> {
logging.log(logging.Debug, "Failed to lookup date, re-calculating")
logging.log(logging.Warning, "Failed to lookup date, re-calculating")
date()
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/mist/internal/http.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import gleam/dict.{type Dict}
import gleam/dynamic.{type Dynamic}
import gleam/erlang/atom.{type Atom}
import gleam/erlang/charlist.{type Charlist}
import gleam/erlang/process.{type ProcessDown, type Selector, type Subject}
import gleam/erlang/process.{type ProcessDown, type Selector}
import gleam/http
import gleam/http/request.{type Request}
import gleam/http/response.{type Response, Response}
Expand All @@ -21,7 +21,7 @@ import gleam/uri
import glisten.{type ClientIp, type Socket}
import glisten/transport.{type Transport}
import mist/internal/buffer.{type Buffer, Buffer}
import mist/internal/clock.{type ClockMessage}
import mist/internal/clock
import mist/internal/encoder
import mist/internal/file

Expand All @@ -47,7 +47,6 @@ pub type Connection {
socket: Socket,
transport: Transport,
client_ip: ClientIp,
clock: Subject(ClockMessage),
)
}

Expand Down
2 changes: 1 addition & 1 deletion src/mist_ffi.erl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@ ets_lookup_element(Table, Key, Position) ->
try
{ok, ets:lookup_element(Table, Key, Position)}
catch
badarg ->
error:badarg ->
{error, nil}
end.
Loading

0 comments on commit 4dcb6d5

Please sign in to comment.