# `Lightning.Collaboration.Registry`
[🔗](https://github.com/OpenFn/lightning/blob/main/lib/lightning/collaboration/registry.ex#L1)

Registry for collaboration processes.

This Registry provides local process tracking for the collaboration system,
complementing the cluster-wide :pg process groups. It supports the following
key patterns:

## Supported Key Patterns

- `{:shared_doc, document_name}` - SharedDoc processes for documents (e.g., "workflow:workflow_id")
- `{:persistence_writer, document_name}` - PersistenceWriter processes (future use)
- `{:doc_supervisor, workflow_id}` - DocumentSupervisor processes (future use)

Session processes are not registered here as there may be multiple sessions
for the same workflow and the same user.

## Registry vs Process Groups

This Registry is used for local node process lookup and coordination, while
`:pg` (process groups) remains for cluster-wide SharedDoc uniqueness. The
Registry provides faster local lookups and better integration with supervision
trees.

## Usage

Processes can register themselves either in their init callback or using via tuples
in their child_spec:

    # Session registration in init callback
    Lightning.Collaboration.Registry.register({:session, "workflow_123", "user_456"})

    # SharedDoc registration via child_spec
    {SharedDoc, [
      doc_name: "workflow:workflow_123",
      name: {:via, Registry, {Lightning.Collaboration.Registry.registry_name(), {:shared_doc, "workflow:workflow_123"}}}
    ]}

# `child_spec`

Child specification for starting the Registry.

The registered name is injectable via the `:name` option (defaulting to
`__MODULE__`) so a supervisor instance can run its own Registry.

# `count`

Count registered processes, optionally restricted to a key prefix.

A `nil` key counts every entry in the registry; any other key counts entries
whose key starts with it. The one-argument form takes the key, not the
registry — `count("workflow:x")` uses the default registry.

# `get_group`

# `lookup`

```elixir
@spec lookup(registry :: atom(), term()) :: [{pid(), term()}]
```

Look up all processes registered with the given key.

Returns a list of {pid, value} tuples. Since we use unique keys,
this will typically return a single-item list or an empty list.

## Examples

    Lightning.Collaboration.Registry.lookup({:session, "workflow_123"})
    # => [{#PID<0.123.0>, nil}]

    Lightning.Collaboration.Registry.lookup({:session, "nonexistent"})
    # => []

# `register`

```elixir
@spec register(registry :: atom(), term()) ::
  {:ok, pid()} | {:error, {:already_registered, pid()}}
```

Register the current process with the given key.

## Examples

    Lightning.Collaboration.Registry.register({:session, "workflow_123"})
    # => {:ok, #PID<0.123.0>}

    Lightning.Collaboration.Registry.register({:shared_doc, "workflow:workflow_123"})
    # => {:ok, #PID<0.123.0>}

## Error Cases

    Lightning.Collaboration.Registry.register({:session, "workflow_123"})
    # => {:error, {:already_registered, #PID<0.456.0>}}

# `select`

```elixir
@spec select(registry :: atom(), binary()) :: [{term(), pid()}]
```

Select processes registered with the given key (prefix).

The key pattern expected is:
- `{:type, key}`
- `{:type, key, any()}`.

We do a select with any key that _starts with_ the given key.

# `via`

# `whereis`

```elixir
@spec whereis(registry :: atom(), term()) :: pid() | nil
```

Find the pid registered with the given key.

This is a convenience function that returns just the pid, or nil
if no process is registered.

## Examples

    Lightning.Collaboration.Registry.whereis({:session, "workflow_123"})
    # => #PID<0.123.0>

    Lightning.Collaboration.Registry.whereis({:session, "nonexistent"})
    # => nil

---

*Consult [api-reference.md](api-reference.md) for complete listing*
