Skip to content

Commit

Permalink
Merge pull request #3 from tofran/expired-session-pruner
Browse files Browse the repository at this point in the history
Added ExpiredSessionPruner GenServer to clear expired session from the DB
  • Loading branch information
tofran committed Mar 21, 2023
2 parents 3aec54f + 9ae3d96 commit f022a6f
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
4 changes: 2 additions & 2 deletions demo/lib/ecto_sessions_demo/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ defmodule EctoSessionsDemo.Application do
# Start the PubSub system
{Phoenix.PubSub, name: EctoSessionsDemo.PubSub},
# Start the Endpoint (http/https)
EctoSessionsDemoWeb.Endpoint
EctoSessionsDemoWeb.Endpoint,
# Start a worker by calling: EctoSessionsDemo.Worker.start_link(arg)
# {EctoSessionsDemo.Worker, arg}
{EctoSessions.ExpiredSessionPruner, {EctoSessionsDemo.Sessions, :timer.hours(24)}}
]

# See https://hexdocs.pm/elixir/Supervisor.html
Expand Down
67 changes: 67 additions & 0 deletions lib/ecto_sessions/expired_session_pruner.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
defmodule EctoSessions.ExpiredSessionPruner do
@moduledoc """
`GenServer` implementation to delete expired sessions periodically. Given an `EctoSessions` module
and periodicity, in milliseconds.
## Usage
- In your project's `application.ex`:
```
def start(_type, _args) do
children = [
# ...
{EctoSessions.ExpiredSessionPruner, {YourSessionsModule, :timer.hours(24)}}
]
opts = [strategy: :one_for_one, name: EctoSessionsDemo.Supervisor]
Supervisor.start_link(children, opts)
end
```
- Low level usage with `start_link`:
```
GenServer.start_link(
EctoSessions.ExpiredSessionPruner,
{YourSessionsModule, 10_000}
)
```
Where `YourSessionsModule` is any module that uses `EctoSessions` and the second argument the
number of milliseconds to 'sleep' between cycles. Ex: `12 * 60 * 60 * 1000` for 12h. Use `:timer`
for readability.
"""

use GenServer

require Logger

def start_link(args = {module, _sleep_time}) when is_atom(module) do
GenServer.start_link(
__MODULE__,
args,
name: {:global, Module.concat(__MODULE__, module)}
)
end

def init(state = {module, sleep_time}) when is_atom(module) do
Logger.debug("Starting session pruner for #{module} (every #{sleep_time}ms)")

{:ok, prune(state)}
end

def handle_info(:prune, state) do
{:noreply, prune(state)}
end

defp prune(state = {module, sleep_time}) do
delete_count = apply(module, :delete_expired, [])

Logger.info("Deleted #{delete_count} expired sessions with #{module}")

Process.send_after(self(), :prune, sleep_time)

state
end
end

0 comments on commit f022a6f

Please sign in to comment.