Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ad3569a

Browse files
author
Max Hill
committedNov 14, 2024·
feat: included ets_store and postgres_store
1 parent 39dcd04 commit ad3569a

14 files changed

+520
-22
lines changed
 

‎.github/workflows/publish.yml

+14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@ on:
99
jobs:
1010
test:
1111
runs-on: ubuntu-latest
12+
services:
13+
postgres:
14+
image: postgres # Docker Hub image
15+
env:
16+
POSTGRES_PASSWORD: mySuperSecretPassword!
17+
# Set health checks to wait until postgres has started
18+
options: >-
19+
--health-cmd pg_isready
20+
--health-interval 10s
21+
--health-timeout 5s
22+
--health-retries 5
23+
ports:
24+
# Maps tcp port 5432 on service container to the host
25+
- 5432:5432
1226
steps:
1327
- uses: actions/checkout@v4
1428
- uses: erlef/setup-beam@v1

‎.github/workflows/test.yml

+12-1
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,25 @@ on:
1010
jobs:
1111
test:
1212
runs-on: ubuntu-latest
13+
services:
14+
postgres:
15+
image: postgres # Docker Hub image
16+
env:
17+
POSTGRES_PASSWORD: "mySuperSecretPassword!"
18+
options: >-
19+
--health-cmd pg_isready
20+
--health-interval 10s
21+
--health-timeout 5s
22+
--health-retries 5
23+
ports:
24+
- 5432:5432
1325
steps:
1426
- uses: actions/checkout@v4
1527
- uses: erlef/setup-beam@v1
1628
with:
1729
otp-version: "26.0.2"
1830
gleam-version: "1.4.1"
1931
rebar3-version: "3"
20-
# elixir-version: "1.15.4"
2132
- run: gleam deps download
2233
- run: gleam test
2334
- run: gleam format --check src test

‎README.md

+9-14
Original file line numberDiff line numberDiff line change
@@ -152,29 +152,28 @@ which may become a bottleneck under heavy loads.
152152
```gleam
153153
import wisp_kv_sessions/actor_store
154154
155-
use session_store <- result.map(actor_store.try_create_session_store())
155+
use session_store <- result.map(actor_store.new())
156156
157157
// ...
158158
```
159159
See `./example/src/app.gleam` for full example
160160

161161
### postgress_store
162-
The postgres_store uses a [gleam/pgo](https://hexdocs.pm/gleam_pgo/gleam/pgo.html)
163-
connection to store the session information in postgres.
164-
165-
```sh
166-
gleam add wisp_kv_sessions_postgres_store
167-
```
162+
Also included is the postgres_store, that allows you to use postgres as
163+
the storage implementation
168164

169165
```gleam
170166
import wisp_kv_sessions/postgres_store
171167
172-
let db = pgo.connect(pgo.default_config())
168+
let db =
169+
pog.default_config()
170+
|> pog.connect()
171+
173172
// Migrate
174173
use _ <- result.try(postgres_store.migrate_up(conn))
175174
176175
// Setup session_store
177-
use session_store <- result.map(postgres_store.try_create_session_store(conn))
176+
use session_store <- result.map(postgres_store.new(conn))
178177
179178
//...
180179
```
@@ -187,15 +186,11 @@ The ets_store uses [Erlang Term Storage](https://www.erlang.org/doc/apps/stdlib/
187186
and [carpenter](https://hexdocs.pm/carpenter/) to store session information.
188187
*This will NOT be persistant after restarts*. But is a good option for caching.
189188

190-
```sh
191-
gleam add wisp_kv_sessions_ets_store
192-
```
193-
194189
```gleam
195190
import wisp_kv_sessions/ets_store
196191
197192
// Setup session_store
198-
use session_store <- result.map(postgres_store.try_create_session_store(conn))
193+
use session_store <- result.map(ets_store.new(conn))
199194
200195
//...
201196
```

‎gleam.toml

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ gleam_crypto = ">= 1.3.0 and < 2.0.0"
2121
gleam_otp = ">= 0.10.0 and < 1.0.0"
2222
gleam_erlang = ">= 0.25.0 and < 1.0.0"
2323
gleam_http = ">= 3.6.0 and < 4.0.0"
24+
pog = ">= 1.0.0 and < 2.0.0"
25+
carpenter = ">= 0.3.1 and < 1.0.0"
2426

2527
[dev-dependencies]
2628
gleeunit = ">= 1.0.0 and < 2.0.0"

‎justfile

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
1+
#!/usr/bin/env just --justfile
2+
# SETTINGS
3+
# set dotenv-load := true
4+
export DB_PASSWORD:="mySuperSecretPassword!" # Remember to update the DATABASE_URL
5+
export DB_PORT:="6433" # Remember to update the DATABASE_URL
6+
export DB_TAG:="wisp_kv_sessions"
7+
export DB_HOST:="127.0.0.1"
8+
export DB_USER:="postgres"
9+
export DB_NAME:="postgres"
10+
# export DATABASE_URL :="postgres://postgres:mySuperSecretPassword!@localhost:6433/postgres?sslmode=disable"
111

2-
watch-test:
12+
watch_test:
13+
@just db_run &>/dev/null&
14+
@just wait-for-db
315
watchexec --restart --verbose --clear --wrap-process=session --stop-signal SIGTERM --exts gleam --watch ./ -- "gleam test"
16+
17+
test:
18+
@just db_run &>/dev/null&
19+
@just wait-for-db
20+
gleam test
21+
22+
23+
# DB
24+
db_run:
25+
docker run \
26+
--rm \
27+
-p $DB_PORT:5432 \
28+
-e POSTGRES_PASSWORD=$DB_PASSWORD \
29+
-e POSTGRES_USER=$DB_USER \
30+
--name $DB_TAG \
31+
postgres
32+
33+
wait-for-db:
34+
until PGPASSWORD="$DB_PASSWORD" psql -h "$DB_HOST" -U "$DB_USER" -p "$DB_PORT" -c '\q' 2>/dev/null; do echo "Waiting for database..."; sleep 2; done; echo "Database is up!"
35+

‎manifest.toml

+8
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
# You typically do not need to edit this file
33

44
packages = [
5+
{ name = "backoff", version = "1.1.6", build_tools = ["rebar3"], requirements = [], otp_app = "backoff", source = "hex", outer_checksum = "CF0CFFF8995FB20562F822E5CC47D8CCF664C5ECDC26A684CBE85C225F9D7C39" },
56
{ name = "birl", version = "1.7.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "5C66647D62BCB11FE327E7A6024907C4A17954EF22865FE0940B54A852446D01" },
7+
{ name = "carpenter", version = "0.3.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "carpenter", source = "hex", outer_checksum = "7F5AF15A315CF32E8EDD0700BC1E6711618F8049AFE66DFCE82D1161B33F7F1B" },
68
{ name = "exception", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "F5580D584F16A20B7FCDCABF9E9BE9A2C1F6AC4F9176FA6DD0B63E3B20D450AA" },
79
{ name = "filepath", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "EFB6FF65C98B2A16378ABC3EE2B14124168C0CE5201553DE652E2644DCFDB594" },
810
{ name = "gleam_crypto", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_crypto", source = "hex", outer_checksum = "ADD058DEDE8F0341F1ADE3AAC492A224F15700829D9A3A3F9ADF370F875C51B7" },
@@ -18,6 +20,10 @@ packages = [
1820
{ name = "logging", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "logging", source = "hex", outer_checksum = "1098FBF10B54B44C2C7FDF0B01C1253CAFACDACABEFB4B0D027803246753E06D" },
1921
{ name = "marceau", version = "1.2.0", build_tools = ["gleam"], requirements = [], otp_app = "marceau", source = "hex", outer_checksum = "5188D643C181EE350D8A20A3BDBD63AF7B6C505DE333CFBE05EF642ADD88A59B" },
2022
{ name = "mist", version = "1.2.0", build_tools = ["gleam"], requirements = ["birl", "gleam_erlang", "gleam_http", "gleam_otp", "gleam_stdlib", "glisten", "gramps", "hpack_erl", "logging"], otp_app = "mist", source = "hex", outer_checksum = "109B4D64E68C104CC23BB3CC5441ECD479DD7444889DA01113B75C6AF0F0E17B" },
23+
{ name = "opentelemetry_api", version = "1.4.0", build_tools = ["rebar3", "mix"], requirements = [], otp_app = "opentelemetry_api", source = "hex", outer_checksum = "3DFBBFAA2C2ED3121C5C483162836C4F9027DEF469C41578AF5EF32589FCFC58" },
24+
{ name = "pg_types", version = "0.4.0", build_tools = ["rebar3"], requirements = [], otp_app = "pg_types", source = "hex", outer_checksum = "B02EFA785CAECECF9702C681C80A9CA12A39F9161A846CE17B01FB20AEEED7EB" },
25+
{ name = "pgo", version = "0.14.0", build_tools = ["rebar3"], requirements = ["backoff", "opentelemetry_api", "pg_types"], otp_app = "pgo", source = "hex", outer_checksum = "71016C22599936E042DC0012EE4589D24C71427D266292F775EBF201D97DF9C9" },
26+
{ name = "pog", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "pgo"], otp_app = "pog", source = "hex", outer_checksum = "00D57120936AFBF486BE357C472E483C1F0CA507FF9C3668075E87C733CA53F8" },
2127
{ name = "ranger", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "ranger", source = "hex", outer_checksum = "1566C272B1D141B3BBA38B25CB761EF56E312E79EC0E2DFD4D3C19FB0CC1F98C" },
2228
{ name = "simplifile", version = "2.0.1", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "5FFEBD0CAB39BDD343C3E1CCA6438B2848847DC170BA2386DF9D7064F34DF000" },
2329
{ name = "thoas", version = "1.2.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "E38697EDFFD6E91BD12CEA41B155115282630075C2A727E7A6B2947F5408B86A" },
@@ -26,11 +32,13 @@ packages = [
2632

2733
[requirements]
2834
birl = { version = ">= 1.7.1 and < 2.0.0" }
35+
carpenter = { version = ">= 0.3.1 and < 1.0.0" }
2936
gleam_crypto = { version = ">= 1.3.0 and < 2.0.0" }
3037
gleam_erlang = { version = ">= 0.25.0 and < 1.0.0" }
3138
gleam_http = { version = ">= 3.6.0 and < 4.0.0" }
3239
gleam_json = { version = ">= 1.0.1 and < 2.0.0" }
3340
gleam_otp = { version = ">= 0.10.0 and < 1.0.0" }
3441
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
3542
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
43+
pog = { version = ">= 1.0.0 and < 2.0.0" }
3644
wisp = { version = ">= 0.16.0" }

‎src/wisp_kv_sessions.gleam

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub fn set(
111111
let json_data = encoder(data)
112112
let new_session =
113113
session.builder_from(session)
114-
|> session.set_key_value(key, json_data)
114+
|> session.with_entry(key, json_data)
115115
|> session.build
116116
use _ <- result.map(save_session(config, new_session))
117117
data

‎src/wisp_kv_sessions/actor_store.gleam

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type Message(element) {
2424
type Db =
2525
dict.Dict(session.SessionId, session.Session)
2626

27-
pub fn try_create_session_store() {
27+
pub fn new() {
2828
use db <- result.map(
2929
actor.start(dict.new(), handle_message)
3030
|> result.replace_error(session.DbSetupError),

‎src/wisp_kv_sessions/ets_store.gleam

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import carpenter/table
2+
import gleam/list
3+
import gleam/option
4+
import wisp_kv_sessions/session
5+
import wisp_kv_sessions/session_config
6+
7+
pub fn new(table_name) {
8+
let db = new_table(table_name)
9+
session_config.SessionStore(
10+
get_session: get_session(db),
11+
save_session: save_session(db),
12+
delete_session: delete_session(db),
13+
)
14+
}
15+
16+
pub fn new_table(table_name) -> table.Set(String, session.Session) {
17+
// Set up and configure an ETS table
18+
let assert Ok(table) =
19+
table.build(table_name)
20+
|> table.privacy(table.Private)
21+
|> table.write_concurrency(table.AutoWriteConcurrency)
22+
|> table.read_concurrency(True)
23+
|> table.decentralized_counters(True)
24+
|> table.compression(False)
25+
|> table.set
26+
27+
table
28+
}
29+
30+
fn get_session(db) {
31+
fn(session_id: session.SessionId) {
32+
let res =
33+
db
34+
|> table.lookup(session.id_to_string(session_id))
35+
|> list.first
36+
37+
case res {
38+
Ok(tup) -> {
39+
Ok(option.Some(tup.1))
40+
}
41+
Error(_) -> {
42+
Ok(option.None)
43+
}
44+
}
45+
}
46+
}
47+
48+
fn save_session(db) {
49+
fn(new_session: session.Session) {
50+
db
51+
|> table.insert([#(session.id_to_string(new_session.id), new_session)])
52+
Ok(new_session)
53+
}
54+
}
55+
56+
fn delete_session(db) {
57+
fn(session_id: session.SessionId) {
58+
db
59+
|> table.delete(session.id_to_string(session_id))
60+
Ok(Nil)
61+
}
62+
}
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Please sign in to comment.