GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - alii/reki: Registry library for Gleam, much like gen_registry

BranchesTags
Open more actions menu

Latest commit

 

History

75 Commits
75 Commits

Folders and files

NameName
Last commit message
Last commit date
.github/workflows
.github/workflows
 
 
src
src
 
 
test
test
 
 
.gitignore
.gitignore
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 
gleam.toml
gleam.toml
 
 
manifest.toml
manifest.toml
 
 

Repository files navigation

reki

A Gleam actor registry that manages actors by key, similar to Discord's gen_registry in Elixir. It provides a way to look up or start actors on demand ensuring only one actor exists per key, while automatically cleaning up dead processes.

Installation

gleam add reki

Usage

import gleam/erlang/process
import gleam/list
import gleam/option
import gleam/otp/actor
import gleam/otp/static_supervisor as supervisor
import reki

pub type ChannelMsg {
  Subscribe(process.Subject(String))
  Publish(String)
}

pub type ChannelState {
  ChannelState(name: String, subscribers: List(process.Subject(String)))
}

fn start_channel(name: String) {
  actor.new(ChannelState(name:, subscribers: []))
  |> actor.on_message(fn(state, msg) {
    println("Channel" <> state.name <> " received message: " <> inspect(msg))

    case msg {
      Subscribe(sub) ->
        actor.continue(ChannelState(..state, subscribers: [sub, ..state.subscribers]))
      Publish(text) -> {
        list.each(state.subscribers, process.send(_, text))
        actor.continue(state)
      }
    }
  })
  |> actor.start
}

pub fn main() {
  let channels = reki.new()

  let assert Ok(_) =
    supervisor.new(supervisor.OneForOne)
    |> supervisor.add(reki.supervised(channels))
    |> supervisor.start

  let assert Ok(general) =
    reki.lookup_or_start(channels, "general", start_channel)

  let inbox = process.new_subject()
  process.send(general, Subscribe(inbox))

  process.send(general, Publish("Hello!"))

  let assert Ok(same_channel) =
    reki.lookup_or_start(channels, "general", start_channel)

  process.send(same_channel, Publish("Also hello!"))

  // You can also lookup without starting
  case reki.lookup(channels, "general") {
    option.Some(channel) -> process.send(channel, Publish("Found it!"))
    option.None -> {
      // channel not found ...
      todo
    }
  }
}

How it works

Like gen_registry, reki is an Erlang gen_server that stores {key, subject} mappings in ETS for fast O(1) lookups. The gen_server serializes "lookup or start" operations to prevent races when multiple processes request the same key simultaneously.

  • Fast reads: Existing actors are looked up directly from ETS, bypassing the gen_server
  • Automatic cleanup: The registry links to child processes and traps exits, removing entries from ETS when they die
  • Concurrent safety: Start operations are serialized through the gen_server

About

Registry library for Gleam, much like gen_registry

hexdocs.pm/reki/

Topics

actorerlanggleamregistry

Resources

Readme
MIT license
Activity

Stars

11 stars

Watchers

0 watching

Forks

1 fork
Report repository

Releases

Contributors

Languages

You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.