135 lines
3.9 KiB
Markdown
135 lines
3.9 KiB
Markdown
# gex = gajumaru exchange
|
|
|
|
Currently there is only one thing, which is the Gajumaru HTTP Daemon.
|
|
|
|
## How to run `gex_httpd`
|
|
|
|
Last updated: September 23, 2025 (PRH).
|
|
|
|
1. **Install Erlang and zx/zomp**
|
|
|
|
Source: [*Building Erlang 26.2.5 on Ubuntu 24.04*](https://zxq9.com/archives/2905)
|
|
|
|
Adapt this to your Linux distribution.
|
|
|
|
1.a. **Install necessary build tools**
|
|
|
|
```bash
|
|
sudo apt update
|
|
sudo apt upgrade
|
|
sudo apt install \
|
|
gcc curl g++ dpkg-dev build-essential automake autoconf \
|
|
libncurses-dev libssl-dev flex xsltproc libwxgtk3.2-dev \
|
|
wget vim git
|
|
```
|
|
|
|
1.b. **Put [Kerl](https://github.com/kerl/kerl) somewhere in your
|
|
`$PATH`**. This is a tool to build Erlang releases.
|
|
|
|
```bash
|
|
wget -O ~/bin/kerl https://raw.githubusercontent.com/kerl/kerl/master/kerl
|
|
chmod u+x ~/bin/kerl
|
|
```
|
|
|
|
1.c. **Build Erlang from source using Kerl**
|
|
|
|
```bash
|
|
kerl update releases
|
|
## use the most recent one that looks stable
|
|
## you do need to type the number twice, that's not a typo
|
|
kerl build 28.1 28.1
|
|
kerl install 28.1 ~/.erts/28.1
|
|
```
|
|
|
|
1.d. **Put Erlang in your `$PATH`**
|
|
|
|
Update .bashrc or .zshrc or whatever with the following line:
|
|
|
|
```bash
|
|
. $HOME/.erts/28.1/activate
|
|
```
|
|
|
|
|
|
1.e. **Install zx**
|
|
|
|
```bash
|
|
wget -q https://zxq9.com/projects/zomp/get_zx && bash get_zx
|
|
```
|
|
|
|
1.f. **Test zx works**
|
|
|
|
zx installs itself to `~/bin`, so make sure that's in your
|
|
`$PATH`.
|
|
|
|
```bash
|
|
zx run erltris
|
|
```
|
|
|
|
|
|
## Notes
|
|
|
|
### Big Picture: telnet chat server -> HTTP server
|
|
|
|
- The default project (see initial commit) is a telnet echo server. It's like
|
|
the most ghetto low-budget chat server imaginable.
|
|
|
|

|
|
|
|
Lefty and middley can chat just like normal.
|
|
|
|
However, righty (`curl`) foolishly thinks he is talking to an HTTP server.
|
|
His request is echoed to lefty and middley.
|
|
|
|
Curl crashed because instead of a valid HTTP response back, he got something
|
|
like
|
|
|
|
```
|
|
MESSAGE from YOU: GET / HTTP/1.1
|
|
```
|
|
|
|
- We make this into an HTTP server by replacing the "echo my message to
|
|
everyone else" logic with "parse this message as an HTTP request and send
|
|
back an HTTP response" logic.
|
|
- Our "application logic" or "business logic" or whatever is contained in that
|
|
process of how the request is mapped to a response.
|
|
- It really is not more complicated than that.
|
|
|
|
### Basics of Erlang Processes
|
|
|
|
These are heuristics that are good starting points
|
|
|
|
- each module ~= 1 process
|
|
- it helps to think of erlang as an operating system, and erlang modules as
|
|
shell scripts that run in that operating system.
|
|
- some modules correspond to fungible processes, some are non-fungible
|
|
- in Observer (`observer:start()`)
|
|
- named processes are non-fungible (e.g. `gh_client_sup`)
|
|
- the name can be anything, but conventionally it's the module name
|
|
- fungible processes have numbers (PIDs) (e.g. the `gh_client` code)
|
|
- named processes also have PIDs, they just also have names
|
|
|
|

|
|
|
|
|
|
### Following the call chain of `gex_httpd:listen(8080)`
|
|
|
|
- Reference commit: `49a09d192c6f2380c5186ec7d81e98785d667214`
|
|
- By default, the telnet server doesn't occupy a port
|
|
- `gex_httpd:listen(8080)` tells it to listen on port 8080
|
|
|
|
```
|
|
%% gex_httpd.erl
|
|
-spec listen(PortNum) -> Result
|
|
when PortNum :: inet:port_num(),
|
|
Result :: ok
|
|
| {error, {listening, inet:port_num()}}.
|
|
%% @doc
|
|
%% Make the server start listening on a port.
|
|
%% Returns an {error, Reason} tuple if it is already listening.
|
|
|
|
listen(PortNum) ->
|
|
gh_client_man:listen(PortNum).
|
|
|
|
|
|
%%
|