erlang
Tags: programming languages
- https://erlangexplained.com/index.php/about
- https://learnyousomeerlang.com/
- https://www.erlang-in-anger.com/
- https://blog.stenmans.org/theBeamBook/
- http://erlang.org/doc/reference_manual/introduction.html
- https://ferd.ca/the-zen-of-erlang.html
- https://erlangforums.com/
- https://medium.com/erlang-battleground
- https://medium.com/erlang-battleground/property-based-testing-erlang-elixir-de72ad24966b
- https://github.com/stevana/armstrong-distributed-systems/blob/main/docs/erlang-is-not-about.md#user-content-fn-0-b236052c3934bd6f7ea3426445bf45af
- https://www.erlang-factory.com/conference/ErlangUserConference2011/speakers/ScottLystigFritchie
- https://adoptingerlang.org/docs/development/otp_high_level/
Erlang/OTP 24 Highlights
- https://blog.erlang.org/My-OTP-24-Highlights/#EEP-56-supervisor-automatic-shutdown
- removed 320k lines of code!
Erlang Projects
Interop
Rustler
- rust bridge for erlang
- https://github.com/rusterlium/rustler
Erlang Scaling Limitations
- https://learnyousomeerlang.com/distribunomicon#burying-the-distribunomicon
- https://www.youtube.com/watch?v=KrwhOkiifQ8
- https://arxiv.org/abs/1802.02652
- https://www.dcs.gla.ac.uk/~amirg/publications/DE-Bench.pdf
- https://github.com/max-au/spg
- https://max-au.com/peer/
json with erlang
Supervisor Trees for golang
Nif Issues
- Monitoring for elixir
- https://github.com/massemanet/redbug
- https://www.erlang.org/doc/apps/tools/lcnt_chapter.html
- https://www.erlang.org/doc/man/scheduler.html#sample_all-0
- https://erlangforums.com/t/find-out-whats-running-on-dirty-schedulers/2885/3
- https://www.erlang.org/doc/apps/erts/beamasm#linux-perf-support - linux
- https://medium.com/@jlouis666/erlang-dirty-scheduler-overhead-6e1219dcc7
- https://blog.jola.dev/patterns-for-managing-ets-tables#menu
Enabling
:erlang.system_flag(:scheduler_wall_time, true)
a = :schedulers.get_sample()
b = :schedulers.get_sample()
:schedulers.utilization(a, b)
emacs
Cowboy Web Server
-
https://gist.github.com/weaversam8/c77fe1df5749d6eaa459d9e1b6f61d9d - fully documented stream handler
-module(reference_stream_h). -behavior(cowboy_stream). -export([init/3]). -export([data/4]). -export([info/3]). -export([terminate/3]). -export([early_error/5]). -record(state, {next}). %% %% Callback Functions %% % This implementation was modeled from imetrics_cowboy_stream_h. % This is a ready-to-use template that other stream handlers can be % based on. % This function is called when the request is first received and the % headers are parsed and known. -spec init(cowboy_stream:streamid(), cowboy_req:req(), cowboy:opts()) -> {cowboy_stream:commands(), #state{}}. init(StreamID, Req = #{ path := Path }, Opts) -> % The state record here holds our "Next" tuple, which contains a reference % to ourselves (module) and a state maintained by the cowboy_stream module. % It can be passed around opaquely. State0 = #state{}, % When we're ready to invoke the next handler in the chain, we call % cowboy_stream:init/3. It returns that "Next" tuple and a list of "commands" % to send to the upstream HTTP process. Those commands are documented [here][0] % % [0]: https://ninenines.eu/docs/en/cowboy/2.8/manual/cowboy_stream/#commands {Commands0, Next} = cowboy_stream:init(StreamID, Req, Opts), % We pass these commands thru our "fold" function, which allows us to iterate % thru each command and modify it if necessary. We can also add new commands % here or in that function if we want to. Ultimately, the list of commands is % returned by this function, and passed to the next handler upstream (or cowboy, % which passes them to the client, if this is the last handler.) fold(Commands0, State0#state{next=Next}). % This function is called with the data sent in the request body. It can be called in % chunks, so make sure to check the "IsFin" flag to decide whether you've received % all the data. -spec data(cowboy_stream:streamid(), cowboy_stream:fin(), cowboy_req:resp_body(), State) -> {cowboy_stream:commands(), State} when State::#state{}. data(StreamID, IsFin, Data, State0=#state{next=Next0}) -> % Invoke the next stream handler in the chain. {Commands0, Next} = cowboy_stream:data(StreamID, IsFin, Data, Next0), % Process any commands returned by downstream stream handlers. fold(Commands0, State0#state{next=Next}). % Any messages addressed to the stream will be sent to this function. Cowboy also uses % this function to inform stream handlers of internal events. -spec info(cowboy_stream:streamid(), any(), State) -> {cowboy_stream:commands(), State} when State::#state{}. info(StreamID, Info, State0=#state{next=Next0}) -> % Invoke the next stream handler in the chain. {Commands0, Next} = cowboy_stream:info(StreamID, Info, Next0), % Process any commands returned by downstream stream handlers. fold(Commands0, State0#state{next=Next}). % All streams will eventually be terminated and this function will be called. The % only time when terminate/3 is not called is when an error occurs in init/3 of % any stream handler, since the state is not available. -spec terminate(cowboy_stream:streamid(), cowboy_stream:reason(), #state{}) -> any(). terminate(StreamID, Reason, #state{next=Next}) -> % Propagate the terminate to downstream stream handlers. cowboy_stream:terminate(StreamID, Reason, Next). % This function will be called when an error occurs before the request-line and % all headers have been received in an HTTP/1.1 request. It includes the partial % request, and the response Cowboy intends to send. The return value of this % function is the response, so it allows you to modify it if necessary. -spec early_error(cowboy_stream:streamid(), cowboy_stream:reason(), cowboy_stream:partial_req(), Resp, cowboy:opts()) -> Resp when Resp::cowboy_stream:resp_command(). early_error(StreamID, Reason, PartialReq, Resp, Opts) -> % Propagate the error to downstream stream handlers. cowboy_stream:early_error(StreamID, Reason, PartialReq, Resp, Opts). %% %% Internal Functions %% % Any commands (see [0]) returned from downstream handlers are passed thru this % fold function, giving us the chance to modify, omit, replace, or append to them. % % This module transparently passes the commands thru without any changes, but this % logic remains in place since this is the best documented stream handler in all of % our codebases, and it should exist as a reference for other stream handlers to hook % into in the future. % % [0]: https://ninenines.eu/docs/en/cowboy/2.8/manual/cowboy_stream/#commands fold(Commands, State) -> fold(Commands, State, []). % At the end of the recursion, reverse the accumulator so the original order of % commands is preserved. fold([], State, Acc) -> {lists:reverse(Acc), State}; % You can add additional cases here to catch specific commands. % fold([{response, ResponseCode, Headers, Body0}|Tail], State0, Acc) -> % % do something with the body % Body = do_something(Body0), % Response = {response, ResponseCode, Headers, Body}, % fold(Tail, State0, [Response|Acc]); % This is the catch-all case for any commands we didn't match above, pass it % thru unmodified. fold([Command|Tail], State, Acc) -> fold(Tail, State, [Command|Acc]).
Installing on M1
export KERL_CONFIGURE_OPTIONS="--without-javac --with-ssl=$(brew --prefix openssl@3) --without-odbc"
asdf install erlang 26.2.1
rust Killing Senders by Sending Back Unexpected Responses
Dist
-
look for
erts_term
and other stuff -
BEAM JIT’d too, usually stuff like
beam_jit:binary_to_term